@speakableio/core 1.0.29 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers/SpeakableProvider.tsx","../src/utils/error-handler.ts","../src/lib/firebase/api.ts","../src/domains/assignment/assignment.constants.ts","../src/domains/assignment/services/get-assignments-score.service.ts","../src/domains/assignment/services/attach-score-assignment.service.ts","../src/domains/assignment/services/get-all-assignment.service.ts","../src/domains/assignment/utils/check-assignment-availability.ts","../src/domains/assignment/services/get-assignment.service.ts","../src/domains/assignment/assignment.repo.ts","../src/domains/assignment/hooks/assignment.hooks.ts","../src/domains/assignment/hooks/score-hooks.ts","../src/utils/debounce.utils.ts","../src/lib/tanstack/handle-optimistic-update-query.ts","../src/constants/speakable-plans.ts","../src/hooks/usePermissions.ts","../src/domains/notification/notification.constants.ts","../src/domains/notification/services/create-notification.service.ts","../src/constants/web.constants.ts","../src/domains/notification/services/send-notification.service.ts","../src/domains/notification/hooks/notification.hooks.ts","../src/hooks/useGoogleClassroom.ts","../src/lib/firebase/firebase-analytics/grading-standard.ts","../src/constants/analytics.constants.ts","../src/lib/firebase/firebase-analytics/assignment.ts","../src/domains/assignment/utils/create-default-score.ts","../src/domains/assignment/score-practice.constants.ts","../src/domains/assignment/services/create-score.service.ts","../src/domains/assignment/services/get-score.service.ts","../src/domains/assignment/utils/calculateScoreAndProgress.ts","../src/domains/assignment/services/update-score.service.ts","../src/domains/assignment/services/clear-score.service.ts","../src/domains/assignment/services/submit-assignment-score.service.ts","../src/domains/cards/card.hooks.ts","../src/domains/cards/card.model.ts","../src/domains/cards/card.constants.ts","../src/domains/cards/services/get-card.service.ts","../src/domains/cards/services/create-card.service.ts","../src/utils/text-utils.ts","../src/domains/cards/services/get-card-verification-status.service.ts","../src/domains/cards/card.repo.ts","../src/domains/cards/utils/check-page-type.ts","../src/domains/cards/utils/get-page-prompt.ts","../src/domains/cards/utils/get-completed-pages.ts","../src/domains/cards/utils/get-label-page.ts","../src/domains/cards/utils/get-page-media-data.ts","../src/domains/sets/set.hooks.ts","../src/domains/sets/set.constants.ts","../src/domains/sets/services/get-set.service.ts","../src/domains/sets/set.repo.ts","../src/utils/ai/detect-transcript-hallucionation.ts","../src/utils/ai/get-transcript.ts","../src/constants/all-langs.json","../src/utils/ai/get-respond-card-tool.ts","../src/hooks/useActivity.ts","../src/services/add-grading-standard.ts","../src/hooks/useActivityTracker.ts","../src/hooks/useCredits.ts","../src/hooks/useOrganizationAccess.ts","../src/hooks/useSpeakableTranscript.ts","../src/hooks/useUpdateStudentVoc.ts","../src/hooks/useActivityFeedbackAccess.ts","../src/hooks/useOpenAI.ts","../src/lib/create-firebase-client-native.ts","../src/lib/create-firebase-client.ts"],"sourcesContent":["import React, { createContext, useContext, useEffect, useState } from 'react'\nimport { type QueryClient } from '@tanstack/react-query'\nimport { type FsClient } from '@core/lib/create-firebase-client'\nimport { type User } from '@core/types/user.types'\nimport { type Permissions } from '@core/types/permissions.types'\n\ninterface FsContext {\n speakableApi: Awaited<FsClient>\n queryClient: QueryClient\n user: User\n permissions: Permissions\n}\n\nexport const FsCtx = createContext<FsContext | null>(null)\n\nexport function SpeakableProvider({\n user,\n children,\n queryClient,\n permissions,\n fsClient,\n}: {\n children: React.ReactNode\n fsClient: FsClient\n permissions: Permissions\n queryClient: QueryClient\n user: User\n}) {\n const [speakableApi, setSpeakableApi] = useState<null | Awaited<FsClient>>(null)\n\n useEffect(() => {\n setSpeakableApi(fsClient)\n }, [fsClient])\n\n if (!speakableApi) return null\n\n return (\n <FsCtx.Provider\n value={{\n speakableApi,\n queryClient,\n user,\n permissions,\n }}\n >\n {children}\n </FsCtx.Provider>\n )\n}\n\nexport function useSpeakableApi() {\n const ctx = useContext(FsCtx)\n\n if (!ctx) throw new Error('useSpeakableApi must be used within a SpeakableProvider')\n\n return ctx\n}\n","// error-handler.ts\nimport { type FirebaseError } from 'firebase/app'\n\nexport class ServiceError extends Error {\n constructor(\n message: string,\n public readonly originalError?: unknown,\n public readonly code?: string,\n ) {\n super(message)\n this.name = 'ServiceError'\n }\n}\n\n// Preservamos los tipos de los parámetros\ntype AsyncFunction<T, P extends any[] = any[]> = (...args: P) => Promise<T>\n\nexport function withErrorHandler<T, P extends any[]>(\n fn: AsyncFunction<T, P>,\n serviceName: string,\n): AsyncFunction<T, P> {\n return async (...args: P): Promise<T> => {\n try {\n return await fn(...args)\n } catch (error) {\n // Log the error for debugging\n console.error(`Service ${serviceName} failed with args:`, args)\n console.error('Error details:', error)\n \n if (error instanceof Error && 'code' in error) {\n const firebaseError = error as FirebaseError\n\n throw new ServiceError(\n `Error in ${serviceName}: ${firebaseError.message}`,\n error,\n firebaseError.code,\n )\n }\n\n if (error instanceof Error) {\n throw new ServiceError(`Error in ${serviceName}: ${error.message}`, error)\n }\n\n throw new ServiceError(`Unknown error in ${serviceName}`, error)\n }\n }\n}\n","import { type CallableFunction, type FirestoreHelpers } from '@core/types/firebase.types'\nimport {\n type SetOptions,\n type DocumentData,\n type QueryConstraint,\n type WithFieldValue,\n type Firestore,\n} from 'firebase/firestore'\n\ninterface FirebaseConfig {\n db: Firestore\n helpers: FirestoreHelpers\n httpsCallable: (name: string) => CallableFunction\n logEvent: (name: string, data: any) => void\n}\n\ntype FirebasePath = string\n\nexport class FirebaseAPI {\n private static instance: FirebaseAPI\n private config: FirebaseConfig | null = null\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private constructor() {\n // Private constructor for singleton pattern\n }\n\n static getInstance(): FirebaseAPI {\n if (!FirebaseAPI.instance) {\n FirebaseAPI.instance = new FirebaseAPI()\n }\n\n return FirebaseAPI.instance\n }\n\n initialize(config: FirebaseConfig) {\n this.config = config\n }\n\n get db() {\n if (!this.config) throw new Error('Firebase API not initialized')\n\n return this.config.db\n }\n\n get helpers() {\n if (!this.config) throw new Error('Firebase API not initialized')\n\n return this.config.helpers\n }\n\n get httpsCallable() {\n return this.config?.httpsCallable\n }\n\n logEvent(name: string, data: any) {\n this.config?.logEvent(name, data)\n }\n\n accessQueryConstraints() {\n const { query, orderBy, limit, startAt, startAfter, endAt, endBefore, where, increment } =\n this.helpers\n\n return {\n query,\n orderBy,\n limit,\n startAt,\n startAfter,\n endAt,\n endBefore,\n where,\n increment,\n }\n }\n\n accessHelpers() {\n const { doc, collection, writeBatch, serverTimestamp, setDoc } = this.helpers\n\n return {\n doc: (path: FirebasePath) => doc(this.db, path),\n collection: (path: FirebasePath) => collection(this.db, path),\n writeBatch: () => writeBatch(this.db),\n serverTimestamp: serverTimestamp,\n setDoc: setDoc,\n }\n }\n\n async getDoc<T>(path: FirebasePath) {\n const { getDoc, doc } = this.helpers\n\n const docRef = doc(this.db, path)\n const docSnap = await getDoc(docRef)\n\n const data = docSnap.exists()\n ? ({\n ...docSnap.data(),\n id: docSnap.id,\n } as T)\n : null\n\n return {\n id: docSnap.id,\n data,\n }\n }\n\n async getDocs<T>(path: FirebasePath, ...queryConstraints: QueryConstraint[]) {\n const { getDocs, query, collection } = this.helpers\n const collectionRef = collection(this.db, path)\n const q =\n queryConstraints.length > 0 ? query(collectionRef, ...queryConstraints) : collectionRef\n\n const querySnapshot = await getDocs(q)\n\n const data = querySnapshot.docs.map(doc => ({\n data: doc.data() as T,\n id: doc.id,\n }))\n\n return {\n data: data as unknown as (T & {\n id: string\n })[],\n querySnapshot,\n empty: querySnapshot.empty,\n }\n }\n\n async addDoc<T extends WithFieldValue<DocumentData>>(\n path: FirebasePath,\n data: T,\n ): Promise<{ id: string } & T> {\n const { addDoc, collection } = this.helpers\n const collectionRef = collection(this.db, path)\n const docRef = await addDoc(collectionRef, data)\n\n return {\n ...data,\n id: docRef.id,\n }\n }\n\n async setDoc<T extends WithFieldValue<DocumentData>>(\n path: FirebasePath,\n data: T,\n options: SetOptions = {},\n ): Promise<void> {\n const { setDoc, doc } = this.helpers\n const docRef = doc(this.db, path)\n\n await setDoc(docRef, data, options)\n }\n\n async updateDoc(path: FirebasePath, data: any): Promise<void> {\n const { updateDoc, doc } = this.helpers\n\n const docRef = doc(this.db, path)\n\n await updateDoc(docRef, data)\n }\n\n async deleteDoc(path: FirebasePath): Promise<void> {\n const { deleteDoc, doc } = this.helpers\n const docRef = doc(this.db, path)\n\n await deleteDoc(docRef)\n }\n\n async runTransaction<T>(updateFunction: (transaction: any) => Promise<T>): Promise<T> {\n const { runTransaction } = this.helpers\n\n return runTransaction(this.db, updateFunction)\n }\n\n async runBatch(operations: (() => Promise<void>)[]): Promise<void> {\n const { writeBatch } = this.helpers\n const batch = writeBatch(this.db)\n\n await Promise.all(operations.map(op => op()))\n await batch.commit()\n }\n\n writeBatch() {\n const { writeBatch } = this.helpers\n\n const batch = writeBatch(this.db)\n\n return batch\n }\n}\n\nexport const api = FirebaseAPI.getInstance()\n","export enum AssignmentAnalyticsType {\n Macro = 'macro',\n Gradebook = 'gradebook',\n Cards = 'cards',\n Student = 'student',\n StudentSummary = 'student_summary',\n All = 'all',\n}\n\nexport const ASSIGNMENT_ANALYTICS_TYPES = [\n AssignmentAnalyticsType.Macro,\n AssignmentAnalyticsType.Gradebook,\n AssignmentAnalyticsType.Cards,\n AssignmentAnalyticsType.Student,\n AssignmentAnalyticsType.StudentSummary,\n]\n\nconst ASSIGNMENTS_COLLECTION = 'assignments'\nconst ANALYTICS_SUBCOLLECTION = 'analytics'\nconst SCORES_SUBCOLLECTION = 'scores'\n\nexport type RefsAssignmentFiresotre =\n `${typeof ASSIGNMENTS_COLLECTION}/${string}${`/${typeof ANALYTICS_SUBCOLLECTION}/${string}` | `/${typeof SCORES_SUBCOLLECTION}/${string}` | ''}`\n\nexport const refsAssignmentFiresotre = {\n allAssignments: () => ASSIGNMENTS_COLLECTION,\n assignment: (params: { id: string }) => `${ASSIGNMENTS_COLLECTION}/${params.id}` as const,\n assignmentAllAnalytics: (params: { id: string }) =>\n `${ASSIGNMENTS_COLLECTION}/${params.id}/${ANALYTICS_SUBCOLLECTION}` as const,\n assignmentAnalytics: (params: { id: string; type: string }) =>\n `${ASSIGNMENTS_COLLECTION}/${params.id}/${ANALYTICS_SUBCOLLECTION}/${params.type}` as const,\n assignmentScores: (params: { id: string; userId: string }) =>\n `${ASSIGNMENTS_COLLECTION}/${params.id}/${SCORES_SUBCOLLECTION}/${params.userId}` as const,\n}\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport {\n ASSIGNMENT_ANALYTICS_TYPES,\n AssignmentAnalyticsType,\n refsAssignmentFiresotre,\n} from '../assignment.constants'\n\nconst _getAssignmentScores = async ({\n assignmentId,\n analyticType = AssignmentAnalyticsType.Macro,\n studentId,\n currentUserId,\n}: {\n assignmentId: string\n currentUserId: string\n analyticType?: AssignmentAnalyticsType\n studentId?: string\n}) => {\n if (analyticType === AssignmentAnalyticsType.Student) {\n const path = refsAssignmentFiresotre.assignmentScores({\n id: assignmentId,\n userId: currentUserId,\n })\n const response = await api.getDoc(path)\n\n return { scores: response.data, id: assignmentId }\n }\n\n if (analyticType === AssignmentAnalyticsType.StudentSummary && studentId) {\n const path = refsAssignmentFiresotre.assignmentScores({\n id: assignmentId,\n userId: studentId,\n })\n const response = await api.getDoc(path)\n\n return { scores: response.data, id: assignmentId }\n }\n\n if (\n analyticType !== AssignmentAnalyticsType.All &&\n ASSIGNMENT_ANALYTICS_TYPES.includes(analyticType)\n ) {\n const ref = refsAssignmentFiresotre.assignmentAnalytics({\n id: assignmentId,\n type: analyticType,\n })\n\n const docData = await api.getDoc(ref)\n\n return { scores: docData.data, id: assignmentId }\n } else if (analyticType === AssignmentAnalyticsType.All) {\n const ref = refsAssignmentFiresotre.assignmentAllAnalytics({ id: assignmentId })\n\n const response = await api.getDocs(ref)\n const data = response.data.reduce((acc, curr) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n acc[curr.id] = curr\n\n return acc\n }, {})\n\n return { scores: data, id: assignmentId }\n }\n}\n\nexport const getAssignmentScores = withErrorHandler(_getAssignmentScores, 'getAssignmentScores')\n","import { withErrorHandler } from '@core/utils/error-handler'\n\nimport { type AssignmentAnalyticsType } from '../assignment.constants'\nimport { type AssignmentWithId } from '../assignment.model'\n\nimport { getAssignmentScores } from './get-assignments-score.service'\n\nconst _attachScoresAssignment = async ({\n assignments,\n analyticType,\n studentId,\n currentUserId,\n}: {\n assignments: AssignmentWithId[]\n analyticType: AssignmentAnalyticsType\n studentId?: string\n currentUserId: string\n}) => {\n const scoresPromises = assignments.map(a => {\n return getAssignmentScores({\n assignmentId: a.id,\n analyticType: analyticType,\n studentId,\n currentUserId,\n })\n })\n const scores = await Promise.all(scoresPromises)\n\n const scoresObject = scores.reduce((acc, curr) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n acc[curr.id] = curr.scores\n\n return acc\n }, {})\n const assignmentsWithScores = assignments.map(a => {\n return {\n ...a,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/ban-ts-comment\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n scores: scoresObject[a.id] ?? null,\n }\n })\n\n return assignmentsWithScores\n}\n\nexport const attachScoresAssignment = withErrorHandler(\n _attachScoresAssignment,\n 'attachScoresAssignment',\n)\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { type AssignmentWithId } from '../assignment.model'\n\nexport async function _getAllAssignments() {\n const path = refsAssignmentFiresotre.allAssignments()\n const response = await api.getDocs<AssignmentWithId>(path)\n\n return response.data\n}\n\nexport const getAllAssignments = withErrorHandler(_getAllAssignments, 'getAllAssignments')\n","import { type CustomTimestamp } from '@core/types/firebase.types'\nimport dayjs from 'dayjs'\n\nexport const checkAssignmentAvailability = (\n scheduledTime: string | CustomTimestamp | null | undefined,\n) => {\n if (!scheduledTime) return true\n\n const scheduledDate =\n typeof scheduledTime === 'string' ? dayjs(scheduledTime) : dayjs(scheduledTime.toDate())\n\n if (!scheduledDate.isValid()) return true\n\n return dayjs().isAfter(scheduledDate)\n}\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { type AssignmentWithId } from '../assignment.model'\nimport { type AssignmentAnalyticsType, refsAssignmentFiresotre } from '../assignment.constants'\nimport { checkAssignmentAvailability } from '../utils/check-assignment-availability'\n\nimport { attachScoresAssignment } from './attach-score-assignment.service'\n\nasync function _getAssignment(params: {\n assignmentId: string\n currentUserId: string\n analyticType?: AssignmentAnalyticsType\n studentId?: string\n}) {\n const path = refsAssignmentFiresotre.assignment({ id: params.assignmentId })\n const response = await api.getDoc<AssignmentWithId>(path)\n\n if (!response.data) return null\n\n const assignment = response.data\n\n const isAvailable = checkAssignmentAvailability(assignment.scheduledTime)\n\n const assignmentWithId: AssignmentWithId = {\n ...assignment,\n isAvailable,\n id: params.assignmentId,\n scheduledTime: assignment.scheduledTime ?? null,\n }\n\n if (params.analyticType) {\n const assignmentsWithScores = await attachScoresAssignment({\n assignments: [assignmentWithId],\n analyticType: params.analyticType,\n currentUserId: params.currentUserId,\n })\n\n return assignmentsWithScores.length > 0 ? assignmentsWithScores[0] : assignmentWithId\n }\n\n return assignmentWithId\n}\n\nexport const getAssignment = withErrorHandler(_getAssignment, 'getAssignment')\n","import { attachScoresAssignment } from './services/attach-score-assignment.service'\nimport { getAllAssignments } from './services/get-all-assignment.service'\nimport { getAssignment } from './services/get-assignment.service'\nimport { getAssignmentScores } from './services/get-assignments-score.service'\n\nexport const createAssignmentRepo = () => {\n return {\n getAssignment: getAssignment,\n attachScoresAssignment: attachScoresAssignment,\n getAssignmentScores: getAssignmentScores,\n getAllAssignments: getAllAssignments,\n }\n}\n","import { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { useQuery } from '@tanstack/react-query'\n\nimport { type AssignmentAnalyticsType } from '../assignment.constants'\n\nexport const assignmentQueryKeys = {\n all: ['assignments'] as const,\n byId: (id: string) => [...assignmentQueryKeys.all, id] as const,\n list: () => [...assignmentQueryKeys.all, 'list'] as const,\n}\n\nexport function useAssignment({\n assignmentId,\n enabled = true,\n analyticType,\n userId,\n}: {\n assignmentId: string\n enabled?: boolean\n analyticType?: AssignmentAnalyticsType\n userId: string\n}) {\n const { speakableApi } = useSpeakableApi()\n\n return useQuery({\n queryKey: assignmentQueryKeys.byId(assignmentId),\n queryFn: () =>\n speakableApi.assignmentRepo.getAssignment({\n assignmentId: assignmentId,\n analyticType,\n currentUserId: userId,\n }),\n enabled,\n })\n}\n","import { useMutation, useQuery } from '@tanstack/react-query'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { type PageActivity } from '@core/domains/cards'\nimport { debounce } from '@core/utils/debounce.utils'\nimport { handleOptimisticUpdate } from '@core/lib/tanstack/handle-optimistic-update-query'\nimport usePermissions from '@core/hooks/usePermissions'\nimport { SpeakableNotificationTypes, useCreateNotification } from '@core/domains/notification'\nimport { useGoogleClassroom } from '@core/hooks/useGoogleClassroom'\nimport { logSubmitAssignment } from '@core/lib/firebase/firebase-analytics'\n\nimport { getScore } from '../services/get-score.service'\nimport { type Score, type PageScore } from '../assignment.model'\nimport calculateScoreAndProgress from '../utils/calculateScoreAndProgress'\nimport { updateCardScore, updateScore } from '../services/update-score.service'\nimport { clearScore, clearScoreV2 } from '../services/clear-score.service'\nimport {\n submitAssignmentScore,\n submitPracticeScore,\n} from '../services/submit-assignment-score.service'\n\nexport const scoreQueryKeys = {\n all: ['scores'] as const,\n byId: (id: string) => [...scoreQueryKeys.all, id] as const,\n list: () => [...scoreQueryKeys.all, 'list'] as const,\n}\n\nexport function useScore({\n isAssignment,\n activityId,\n userId = '',\n courseId,\n enabled = true,\n googleClassroomUserId,\n}: {\n userId: string\n isAssignment: boolean\n activityId: string\n courseId?: string\n enabled?: boolean\n googleClassroomUserId?: string\n}) {\n return useQuery({\n queryFn: () =>\n getScore({\n userId,\n courseId,\n activityId,\n googleClassroomUserId,\n isAssignment,\n }),\n queryKey: scoreQueryKeys.byId(activityId),\n enabled,\n })\n}\n\n// Reduce debounce time to prevent data loss and add better error handling\nconst debounceUpdateScore = debounce(updateScore, 500)\n\nexport function useUpdateScore() {\n const { queryClient } = useSpeakableApi()\n\n const mutation = useMutation({\n mutationFn: debounceUpdateScore,\n onMutate: variables => {\n return handleOptimisticUpdate({\n queryClient,\n queryKey: scoreQueryKeys.byId(variables.activityId),\n newData: variables.data,\n })\n },\n onError: (_, variables, context) => {\n if (context?.previousData)\n queryClient.setQueryData(scoreQueryKeys.byId(variables.activityId), context.previousData)\n },\n onSettled: (_, err, variables) => {\n queryClient.invalidateQueries({\n queryKey: scoreQueryKeys.byId(variables.activityId),\n })\n },\n })\n\n return {\n mutationUpdateScore: mutation,\n }\n}\n\nexport function useUpdateCardScore({\n isAssignment,\n activityId,\n userId,\n cardIds,\n weights,\n}: {\n isAssignment: boolean\n userId: string\n activityId: string\n cardIds: string[]\n weights: Record<string, number>\n}) {\n const { queryClient } = useSpeakableApi()\n\n const queryKey = scoreQueryKeys.byId(activityId)\n\n const mutation = useMutation({\n mutationFn: async ({ cardId, cardScore }: { cardId: string; cardScore: PageScore }) => {\n const previousScores = queryClient.getQueryData<Score>(queryKey)\n\n const { progress, score, newScoreUpdated, updatedCardScore } = getScoreUpdated({\n previousScores: previousScores ?? {},\n cardId,\n cardScore,\n cardIds,\n weights,\n })\n\n await updateCardScore({\n userId,\n cardId,\n isAssignment,\n activityId,\n updates: {\n cardScore: updatedCardScore,\n progress,\n score,\n },\n })\n\n return { cardId, scoresUpdated: newScoreUpdated }\n },\n onMutate: ({ cardId, cardScore }) => {\n // Store previous data before updating\n const previousData = queryClient.getQueryData<Score>(queryKey)\n\n queryClient.setQueryData(queryKey, (previousScore: Partial<Score> | undefined) => {\n const updates = handleOptimisticScore({\n score: previousScore,\n cardId,\n cardScore,\n cardIds,\n weights,\n })\n\n return {\n ...previousScore,\n ...updates,\n }\n })\n\n // Return context with previous data for error recovery\n return { previousData }\n },\n onError: (error, variables, context) => {\n // eslint-disable-next-line no-console\n console.log('Error updating card score:', error.message)\n\n // Revert to previous data if available\n if (context?.previousData) {\n queryClient.setQueryData(queryKey, context.previousData)\n }\n },\n onSettled: () => {\n // Ensure data is fresh after mutation completes\n queryClient.invalidateQueries({\n queryKey,\n })\n },\n })\n\n return {\n mutationUpdateCardScore: mutation,\n }\n}\n\nconst getScoreUpdated = ({\n cardId,\n cardScore,\n previousScores,\n cardIds,\n weights,\n}: {\n previousScores: Partial<Score>\n cardId: string\n cardScore: PageScore\n cardIds: string[]\n weights: Record<string, number>\n}) => {\n const previousCard = previousScores.cards?.[cardId]\n\n const newCardScore = {\n ...(previousCard ?? {}),\n ...cardScore,\n } as PageActivity\n\n const newScores = {\n ...previousScores,\n cards: {\n ...(previousScores.cards ?? {}),\n [cardId]: newCardScore,\n },\n } as Score\n\n const { score, progress } = calculateScoreAndProgress(newScores, cardIds, weights)\n\n return {\n newScoreUpdated: newScores,\n updatedCardScore: cardScore,\n score,\n progress,\n }\n}\n\nconst handleOptimisticScore = ({\n score,\n cardId,\n cardScore,\n cardIds,\n weights,\n}: {\n score: Partial<Score> | undefined\n cardId: string\n cardScore: PageScore\n cardIds: string[]\n weights: Record<string, number>\n}) => {\n let cards = { ...(score?.cards ?? {}) }\n\n cards = {\n ...cards,\n [cardId]: {\n ...cards[cardId],\n ...cardScore,\n },\n }\n const { score: scoreValue, progress } = calculateScoreAndProgress(\n // @ts-ignore\n {\n ...(score ?? {}),\n cards,\n },\n cardIds,\n weights,\n )\n\n return { cards, score: scoreValue, progress }\n}\n\nexport function useClearScore() {\n const { queryClient } = useSpeakableApi()\n\n const mutation = useMutation({\n mutationFn: clearScore,\n onError: error => {\n // eslint-disable-next-line no-console\n console.log('Error clearing score:', error.message)\n },\n onSettled: result => {\n queryClient.invalidateQueries({\n queryKey: scoreQueryKeys.byId(result?.activityId ?? ''),\n })\n },\n })\n\n return {\n mutationClearScore: mutation,\n }\n}\n\nexport function useClearScoreV2() {\n const { queryClient } = useSpeakableApi()\n\n const mutation = useMutation({\n mutationFn: clearScoreV2,\n onError: error => {\n // eslint-disable-next-line no-console\n console.log('Error clearing score V2:', error.message)\n },\n onSettled: result => {\n queryClient.invalidateQueries({\n queryKey: scoreQueryKeys.byId(result?.activityId ?? ''),\n })\n },\n })\n\n return {\n mutationClearScore: mutation,\n }\n}\n\nexport function useSubmitAssignmentScore({\n onAssignmentSubmitted,\n studentName,\n}: {\n onAssignmentSubmitted: (assignmentId: string) => void\n studentName: string\n}) {\n const { queryClient } = useSpeakableApi()\n\n const { hasGoogleClassroomGradePassback } = usePermissions()\n const { submitAssignmentToGoogleClassroom } = useGoogleClassroom()\n const { createNotification } = useCreateNotification()\n\n const mutation = useMutation({\n mutationFn: async ({\n assignment,\n userId,\n cardIds,\n weights,\n scores,\n status,\n }: {\n assignment: {\n id: string\n name: string\n owners: string[]\n courseId: string\n courseWorkId: string\n isAssessment: boolean\n maxPoints: number\n }\n userId: string\n cardIds: string[]\n weights: Record<string, number>\n scores: Score\n status: Score['status']\n // activeCardId: string\n }) => {\n try {\n const scoreUpdated = await submitAssignmentScore({\n assignment,\n userId,\n cardIds,\n weights,\n status,\n studentName: studentName,\n })\n\n if (\n assignment.courseWorkId != null &&\n !assignment.isAssessment &&\n hasGoogleClassroomGradePassback\n ) {\n await submitAssignmentToGoogleClassroom({\n assignment,\n scores,\n })\n }\n\n if (assignment.isAssessment) {\n // New assessment submitted email\n // const data = assessmentSubmittedEmail({\n // studentName: user?.displayName,\n // studentId: userId,\n // teacherName: '!',\n // assignmentId: assignment.id,\n // assignmentTitle: assignment.name,\n // })\n\n // sendEmail(user?.email, data)\n // @ts-ignore\n createNotification(SpeakableNotificationTypes.ASSESSMENT_SUBMITTED, assignment)\n }\n\n if (assignment?.id) {\n logSubmitAssignment({\n courseId: assignment?.courseId,\n })\n }\n\n onAssignmentSubmitted(assignment.id)\n\n queryClient.setQueryData(scoreQueryKeys.byId(assignment.id), {\n ...scores,\n ...scoreUpdated.fieldsUpdated,\n })\n\n return {\n success: true,\n message: 'Score submitted successfully',\n }\n } catch (error) {\n return {\n success: false,\n error: error,\n }\n }\n },\n })\n\n return {\n submitAssignmentScore: mutation.mutateAsync,\n isLoading: mutation.isPending,\n }\n}\n\nexport function useSubmitPracticeScore() {\n const { queryClient } = useSpeakableApi()\n\n const mutation = useMutation({\n mutationFn: async ({\n setId,\n userId,\n scores,\n }: {\n setId: string\n userId: string\n scores: Score\n }) => {\n try {\n await submitPracticeScore({\n setId,\n userId,\n scores,\n })\n\n queryClient.invalidateQueries({\n queryKey: scoreQueryKeys.byId(setId),\n })\n\n return {\n success: true,\n message: 'Score submitted successfully',\n }\n } catch (error) {\n return {\n success: false,\n error: error,\n }\n }\n },\n })\n\n return {\n submitPracticeScore: mutation.mutateAsync,\n isLoading: mutation.isPending,\n }\n}\n","/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\nexport function debounce<T extends (...args: any[]) => Promise<any>>(func: T, waitFor: number) {\n let timeoutId: NodeJS.Timeout | null\n\n return (...args: Parameters<T>): Promise<ReturnType<T>> =>\n new Promise((resolve, reject) => {\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n timeoutId = setTimeout(async () => {\n try {\n const result = await func(...args)\n\n resolve(result)\n } catch (error) {\n reject(error)\n }\n }, waitFor)\n })\n}\n","import { type QueryClient, type QueryKey } from '@tanstack/react-query'\n\nexport const handleOptimisticUpdate = async <T>({\n queryClient,\n queryKey,\n newData,\n}: {\n queryClient: QueryClient\n queryKey: QueryKey\n newData: T\n}) => {\n await queryClient.cancelQueries({\n queryKey,\n })\n\n const previousData = queryClient.getQueryData<T>(queryKey)\n\n if (previousData === undefined) {\n queryClient.setQueryData(queryKey, newData)\n } else {\n queryClient.setQueryData(queryKey, { ...previousData, ...newData })\n }\n\n return { previousData }\n}\n","export const FEEDBACK_PLANS = {\n FEEDBACK_TRANSCRIPT: 'FEEDBACK_TRANSCRIPT', // Transcript from the audio\n FEEDBACK_SUMMARY: 'FEEDBACK_SUMMARY', // Chatty summary (Free plan)\n FEEDBACK_GRAMMAR_INSIGHTS: 'FEEDBACK_GRAMMAR_INSIGHTS', // Grammar insights\n FEEDBACK_SUGGESTED_RESPONSE: 'FEEDBACK_SUGGESTED_RESPONSE', // Suggested Response\n FEEDBACK_RUBRIC: 'FEEDBACK_RUBRIC', // Suggested Response\n FEEDBACK_GRADING_STANDARDS: 'FEEDBACK_GRADING_STANDARDS', // ACTFL / WIDA Estimate\n FEEDBACK_TARGET_LANGUAGE: 'FEEDBACK_TARGET_LANGUAGE', // Ability to set the feedback language to the target language of the student\n FEEDBACK_DISABLE_ALLOW_RETRIES: 'FEEDBACK_DISABLE_ALLOW_RETRIES', // Turn of allow retries\n} as const\n\nexport const AUTO_GRADING_PLANS = {\n AUTO_GRADING_PASS_FAIL: 'AUTO_GRADING_PASS_FAIL', // Pass / fail grading\n AUTO_GRADING_RUBRICS: 'AUTO_GRADING_RUBRICS', // Autograded rubrics\n AUTO_GRADING_STANDARDS_BASED: 'AUTO_GRADING_STANDARDS_BASED', // Standards based grading\n} as const\n\nexport const COMMENTS_PLANS = {\n COMMENTS_SUGGESTIONS: 'COMMENTS_SUGGESTIONS', // Comment suggestions\n} as const\n\nexport const AI_ASSISTANT_PLANS = {\n AI_ASSISTANT_DOCUMENT_UPLOADS: 'AI_ASSISTANT_DOCUMENT_UPLOADS', // Allow document uploading\n AI_ASSISTANT_UNLIMITED_USE: 'AI_ASSISTANT_UNLIMITED_USE', // Allow unlimited use of AI assistant. Otherwise, limits are used.\n} as const\n\nexport const ASSIGNMENT_SETTINGS_PLANS = {\n ASSESSMENTS: 'ASSESSMENTS', // Ability to create assessment assignment types\n GOOGLE_CLASSROOM_GRADE_PASSBACK: 'GOOGLE_CLASSROOM_GRADE_PASSBACK', // Assignment scores can sync with classroom\n} as const\n\nexport const ANALYTICS_PLANS = {\n ANALYTICS_GRADEBOOK: 'ANALYTICS_GRADEBOOK', // Access to the gradebook page\n ANALYTICS_CLASSROOM_ANALYTICS: 'ANALYTICS_CLASSROOM_ANALYTICS', // Access to the classroom analytics page\n ANALYTICS_STUDENT_PROGRESS_REPORTS: 'ANALYTICS_STUDENT_PROGRESS_REPORTS', // Access to the panel that shows an individual student's progress and assignments\n ANALYTICS_ASSIGNMENT_RESULTS: 'ANALYTICS_ASSIGNMENT_RESULTS', // Access to the assigment RESULTS page\n ANALYTICS_ORGANIZATION: 'ANALYTICS_ORGANIZATION', // Access to the organization analytics panel (for permitted admins)\n} as const\n\nexport const SPACES_PLANS = {\n SPACES_CREATE_SPACE: 'SPACES_CREATE_SPACE', // Ability to create spaces\n SPACES_CHECK_POINTS: 'SPACES_CHECK_POINTS', // Feature not available yet. Ability to create checkpoints for spaces for data aggregation\n} as const\n\nexport const DISCOVER_PLANS = {\n DISCOVER_ORGANIZATION_LIBRARY: 'DISCOVER_ORGANIZATION_LIBRARY', // Access to the organizations shared library\n} as const\n\nexport const INTEGRATIONS_PLANS = {\n INTEGRATIONS_LTI: 'INTEGRATIONS_LTI', //Access to all LTI integrations (Canvas, Blackboard, Schoology, etc)\n} as const\n\nexport const MEDIA_AREA_PLANS = {\n MEDIA_AREA_DOCUMENT_UPLOAD: 'MEDIA_AREA_DOCUMENT_UPLOAD',\n MEDIA_AREA_AUDIO_FILES: 'MEDIA_AREA_AUDIO_FILES',\n} as const\n\nexport const FREE_PLAN = []\n\nexport const TEACHER_PRO_PLAN = [\n FEEDBACK_PLANS.FEEDBACK_TRANSCRIPT,\n FEEDBACK_PLANS.FEEDBACK_SUMMARY,\n FEEDBACK_PLANS.FEEDBACK_TARGET_LANGUAGE,\n AUTO_GRADING_PLANS.AUTO_GRADING_PASS_FAIL,\n ANALYTICS_PLANS.ANALYTICS_GRADEBOOK,\n SPACES_PLANS.SPACES_CREATE_SPACE,\n // AUTO_GRADING_PLANS.AUTO_GRADING_STANDARDS_BASED,\n]\n\nexport const SCHOOL_STARTER = [\n FEEDBACK_PLANS.FEEDBACK_TRANSCRIPT,\n FEEDBACK_PLANS.FEEDBACK_SUMMARY,\n FEEDBACK_PLANS.FEEDBACK_GRAMMAR_INSIGHTS,\n FEEDBACK_PLANS.FEEDBACK_SUGGESTED_RESPONSE,\n FEEDBACK_PLANS.FEEDBACK_RUBRIC,\n FEEDBACK_PLANS.FEEDBACK_GRADING_STANDARDS,\n FEEDBACK_PLANS.FEEDBACK_DISABLE_ALLOW_RETRIES,\n FEEDBACK_PLANS.FEEDBACK_TARGET_LANGUAGE,\n AUTO_GRADING_PLANS.AUTO_GRADING_PASS_FAIL,\n AUTO_GRADING_PLANS.AUTO_GRADING_RUBRICS,\n AUTO_GRADING_PLANS.AUTO_GRADING_STANDARDS_BASED,\n AI_ASSISTANT_PLANS.AI_ASSISTANT_DOCUMENT_UPLOADS,\n AI_ASSISTANT_PLANS.AI_ASSISTANT_UNLIMITED_USE,\n // ASSIGNMENT_SETTINGS_PLANS.ASSESSMENTS,\n ASSIGNMENT_SETTINGS_PLANS.GOOGLE_CLASSROOM_GRADE_PASSBACK,\n ANALYTICS_PLANS.ANALYTICS_GRADEBOOK,\n ANALYTICS_PLANS.ANALYTICS_STUDENT_PROGRESS_REPORTS,\n ANALYTICS_PLANS.ANALYTICS_CLASSROOM_ANALYTICS,\n // ANALYTICS_PLANS.ANALYTICS_ORGANIZATION,\n SPACES_PLANS.SPACES_CREATE_SPACE,\n SPACES_PLANS.SPACES_CHECK_POINTS,\n // DISCOVER_PLANS.DISCOVER_ORGANIZATION_LIBRARY,\n MEDIA_AREA_PLANS.MEDIA_AREA_DOCUMENT_UPLOAD,\n MEDIA_AREA_PLANS.MEDIA_AREA_AUDIO_FILES,\n]\n\nexport const ORGANIZATION_PLAN = [\n FEEDBACK_PLANS.FEEDBACK_TRANSCRIPT,\n FEEDBACK_PLANS.FEEDBACK_SUMMARY,\n FEEDBACK_PLANS.FEEDBACK_GRAMMAR_INSIGHTS,\n FEEDBACK_PLANS.FEEDBACK_SUGGESTED_RESPONSE,\n FEEDBACK_PLANS.FEEDBACK_RUBRIC,\n FEEDBACK_PLANS.FEEDBACK_GRADING_STANDARDS,\n FEEDBACK_PLANS.FEEDBACK_DISABLE_ALLOW_RETRIES,\n FEEDBACK_PLANS.FEEDBACK_TARGET_LANGUAGE,\n AUTO_GRADING_PLANS.AUTO_GRADING_PASS_FAIL,\n AUTO_GRADING_PLANS.AUTO_GRADING_RUBRICS,\n AUTO_GRADING_PLANS.AUTO_GRADING_STANDARDS_BASED,\n AI_ASSISTANT_PLANS.AI_ASSISTANT_DOCUMENT_UPLOADS,\n AI_ASSISTANT_PLANS.AI_ASSISTANT_UNLIMITED_USE,\n ASSIGNMENT_SETTINGS_PLANS.ASSESSMENTS,\n ASSIGNMENT_SETTINGS_PLANS.GOOGLE_CLASSROOM_GRADE_PASSBACK,\n ANALYTICS_PLANS.ANALYTICS_GRADEBOOK,\n ANALYTICS_PLANS.ANALYTICS_STUDENT_PROGRESS_REPORTS,\n ANALYTICS_PLANS.ANALYTICS_CLASSROOM_ANALYTICS,\n ANALYTICS_PLANS.ANALYTICS_ORGANIZATION,\n SPACES_PLANS.SPACES_CREATE_SPACE,\n SPACES_PLANS.SPACES_CHECK_POINTS,\n DISCOVER_PLANS.DISCOVER_ORGANIZATION_LIBRARY,\n MEDIA_AREA_PLANS.MEDIA_AREA_DOCUMENT_UPLOAD,\n MEDIA_AREA_PLANS.MEDIA_AREA_AUDIO_FILES,\n]\n\nexport const SpeakablePlanTypes = {\n basic: 'basic',\n teacher_pro: 'teacher_pro',\n school_starter: 'school_starter',\n organization: 'organization',\n // OLD PLANS\n starter: 'starter',\n growth: 'growth',\n professional: 'professional',\n} as const\n\nexport const SpeakablePermissionsMap = {\n [SpeakablePlanTypes.basic]: FREE_PLAN,\n [SpeakablePlanTypes.starter]: TEACHER_PRO_PLAN,\n [SpeakablePlanTypes.teacher_pro]: TEACHER_PRO_PLAN,\n [SpeakablePlanTypes.growth]: ORGANIZATION_PLAN,\n [SpeakablePlanTypes.professional]: ORGANIZATION_PLAN,\n [SpeakablePlanTypes.organization]: ORGANIZATION_PLAN,\n [SpeakablePlanTypes.school_starter]: SCHOOL_STARTER,\n} as const\n\nexport const SpeakablePlanHierarchy = [\n SpeakablePlanTypes.basic,\n SpeakablePlanTypes.starter,\n SpeakablePlanTypes.teacher_pro,\n SpeakablePlanTypes.growth,\n SpeakablePlanTypes.professional,\n SpeakablePlanTypes.school_starter,\n SpeakablePlanTypes.organization,\n] as const\n","import { ANALYTICS_PLANS, ASSIGNMENT_SETTINGS_PLANS } from '@core/constants/speakable-plans'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\n\nconst usePermissions = () => {\n const { permissions } = useSpeakableApi()\n\n const has = (permission: string) => permissions.permissions?.includes(permission)\n\n return {\n plan: permissions.plan,\n permissionsLoaded: permissions.loaded,\n isStripePlan: permissions.isStripePlan,\n refreshDate: permissions.refreshDate,\n isInstitutionPlan: permissions.isInstitutionPlan,\n subscriptionId: permissions.subscriptionId,\n contact: permissions.contact,\n hasGradebook: has(ANALYTICS_PLANS.ANALYTICS_GRADEBOOK),\n hasGoogleClassroomGradePassback: has(ASSIGNMENT_SETTINGS_PLANS.GOOGLE_CLASSROOM_GRADE_PASSBACK),\n hasAssessments: has(ASSIGNMENT_SETTINGS_PLANS.ASSESSMENTS),\n hasSectionAnalytics: has(ANALYTICS_PLANS.ANALYTICS_CLASSROOM_ANALYTICS),\n hasStudentReports: has(ANALYTICS_PLANS.ANALYTICS_STUDENT_PROGRESS_REPORTS),\n permissions: permissions || [],\n hasStudentPortfolios: permissions.hasStudentPortfolios,\n isFreeOrgTrial: permissions.type === 'free_org_trial',\n freeOrgTrialExpired: permissions.freeOrgTrialExpired,\n }\n}\n\nexport default usePermissions\n","export const SPEAKABLE_NOTIFICATIONS = {\n NEW_ASSIGNMENT: 'new_assignment',\n ASSESSMENT_SUBMITTED: 'assessment_submitted',\n ASSESSMENT_SCORED: 'assessment_scored',\n NEW_COMMENT: 'NEW_COMMENT',\n} as const\n\nexport type SpeakableNotificationType =\n (typeof SPEAKABLE_NOTIFICATIONS)[keyof typeof SPEAKABLE_NOTIFICATIONS]\n\nexport const SpeakableNotificationTypes = {\n NEW_ASSIGNMENT: 'NEW_ASSIGNMENT',\n FEEDBACK_FROM_TEACHER: 'FEEDBACK_FROM_TEACHER',\n MESSAGE_FROM_STUDENT: 'MESSAGE_FROM_STUDENT',\n PHRASE_MARKED_CORRECT: 'PHRASE_MARKED_CORRECT',\n STUDENT_PROGRESS: 'STUDENT_PROGRESS',\n PLAYLIST_FOLLOWERS: 'PLAYLIST_FOLLOWERS',\n PLAYLIST_PLAYS: 'PLAYLIST_PLAYS',\n\n // New notifications\n ASSESSMENT_SUBMITTED: 'ASSESSMENT_SUBMITTED', // Notification FOR TEACHER when student submits assessment\n ASSESSMENT_SCORED: 'ASSESSMENT_SCORED', // Notification FOR STUDENT when teacher scores assessment\n // Comment\n NEW_COMMENT: 'NEW_COMMENT',\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { type User } from '@core/types/user.types'\nimport { type AssignmentWithId } from '@core/domains/assignment'\nimport dayjs from 'dayjs'\nimport { WEB_BASE_URL } from '@core/constants/web.constants'\nimport { api } from '@core/lib/firebase/api'\n\nimport { SPEAKABLE_NOTIFICATIONS, type SpeakableNotificationType } from '../notification.constants'\n\nimport { sendNotification } from './send-notification.service'\n\nexport const createNotification = async ({\n data,\n type,\n userId,\n profile,\n}: {\n type: SpeakableNotificationType\n data: any\n userId: string\n profile: User['profile']\n}) => {\n let result\n\n switch (type) {\n case SPEAKABLE_NOTIFICATIONS.NEW_ASSIGNMENT:\n result = await handleAssignNotifPromise({ data, profile })\n break\n case SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SUBMITTED:\n result = await createAssessmentSubmissionNotification({\n data,\n profile,\n userId,\n })\n break\n case SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SCORED:\n result = await createAssessmentScoredNotification({\n data,\n profile,\n })\n break\n default:\n result = null\n break\n }\n\n return result\n}\n\nconst handleAssignNotifPromise = async ({\n data: assignments,\n profile,\n}: {\n data: any[]\n profile: User['profile']\n}) => {\n if (!assignments.length) return\n\n try {\n const notifsPromises = assignments.map(async assignment => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const {\n section,\n section: { members },\n ...rest\n } = assignment\n\n if (!section || !members) throw new Error('Invalid assignment data')\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const data = { section, sendTo: members, assignment: { ...rest } }\n\n return createNewAssignmentNotification({ data, profile })\n })\n\n await Promise.all(notifsPromises)\n\n return {\n success: true,\n message: 'Assignment notifications sent successfully',\n }\n } catch (error) {\n console.error('Error in handleAssignNotifPromise:', error)\n throw error\n }\n}\n\nconst createNewAssignmentNotification = async ({\n data,\n profile,\n}: {\n data: {\n sendTo: string[]\n assignment: AssignmentWithId\n }\n profile: User['profile']\n}) => {\n const { assignment, sendTo } = data\n\n const teacherName = profile.displayName || 'Your teacher'\n const dueDate = assignment.dueDateTimestamp\n ? dayjs(assignment.dueDateTimestamp.toDate()).format('MMM Do')\n : null\n\n const results = await sendNotification(sendTo, {\n courseId: assignment.courseId,\n type: SPEAKABLE_NOTIFICATIONS.NEW_ASSIGNMENT,\n senderName: teacherName,\n link: `${WEB_BASE_URL}/assignment/${assignment.id}`,\n messagePreview: `A new assignment \"${assignment.name}\" is now available. ${dueDate ? `Due ${dueDate}` : ''}`,\n title: 'New Assignment Available!',\n imageUrl: profile.image?.url,\n })\n\n return results\n}\n\nconst createAssessmentSubmissionNotification = async ({\n data: assignment,\n profile,\n userId,\n}: {\n data: AssignmentWithId\n profile: User['profile']\n userId: string\n}) => {\n const studentName = profile.displayName || 'Your student'\n\n const results = await sendNotification(assignment.owners, {\n courseId: assignment.courseId,\n type: SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SUBMITTED,\n link: `${WEB_BASE_URL}/a/${assignment.id}?studentId=${userId}`,\n title: `Assessment Submitted!`,\n senderName: studentName,\n messagePreview: `${studentName} has submitted the assessment \"${assignment.name}\"`,\n imageUrl: profile.image?.url,\n })\n\n return results\n}\n\nconst createAssessmentScoredNotification = async ({\n data,\n profile,\n}: {\n data: {\n assignment: AssignmentWithId\n sendTo: string[]\n }\n profile: User['profile']\n}) => {\n const { assignment, sendTo } = data\n\n const teacherName = profile.displayName || 'Your teacher'\n\n const title = `${assignment.isAssessment ? 'Assessment' : 'Assignment'} Reviewed!`\n const messagePreview = `Your ${assignment.isAssessment ? 'assessment' : 'assignment'} has been reviewed by your teacher. Click to view the feedback.`\n const results = await sendNotification(sendTo, {\n courseId: assignment.courseId,\n type: SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SCORED,\n link: `${WEB_BASE_URL}/assignment/${assignment.id}`,\n title: title,\n messagePreview: messagePreview,\n imageUrl: profile.image?.url,\n senderName: teacherName,\n })\n\n await api.httpsCallable?.('sendAssessmentScoredEmail')?.({\n assessmentTitle: assignment.name,\n link: `${WEB_BASE_URL}/assignment/${assignment.id}`,\n senderImage: profile.image?.url || '',\n studentId: sendTo[0],\n teacherName: profile.displayName,\n })\n\n return results\n}\n","export const WEB_BASE_URL = 'https://app.speakable.io'\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n\nimport { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nconst _sendNotification = async (sendTo: string[], notification: any) => {\n const results = await api.httpsCallable?.('createNotificationV2')?.({\n sendTo,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n notification: notification,\n })\n\n return results\n}\n\nexport const sendNotification = withErrorHandler(_sendNotification, 'sendNotification')\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\n\nimport { createNotification } from '../services/create-notification.service'\nimport { type SpeakableNotificationType } from '../notification.constants'\n\nconst notificationQueryKeys = {\n all: ['notifications'] as const,\n byId: (id: string) => [...notificationQueryKeys.all, id] as const,\n}\n\nexport const useCreateNotification = () => {\n const { user, queryClient } = useSpeakableApi()\n\n const handleCreateNotifications = async (type: SpeakableNotificationType, data: any) => {\n const result = await createNotification({\n type,\n userId: user.auth.uid,\n profile: user?.profile ?? {},\n data,\n })\n\n queryClient.invalidateQueries({\n queryKey: notificationQueryKeys.byId(user?.auth.uid ?? ''),\n })\n\n return result\n }\n\n return {\n createNotification: handleCreateNotifications,\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { type Score } from '@core/domains/assignment'\nimport { api } from '@core/lib/firebase/api'\n\nexport const useGoogleClassroom = () => {\n const submitAssignmentToGoogleClassroom = async ({\n assignment,\n scores,\n googleUserId = null, // optional to override the user's googleUserId\n }: {\n assignment: {\n id: string\n name: string\n owners: string[]\n courseId: string\n courseWorkId: string\n isAssessment: boolean\n maxPoints: number\n }\n scores: Score\n googleUserId?: string | null\n }) => {\n try {\n const { googleClassroomUserId = null } = scores\n const googleId = googleUserId || googleClassroomUserId\n\n if (!googleId)\n return {\n error: true,\n message: 'No Google Classroom ID found',\n }\n const { courseWorkId, maxPoints, owners, courseId } = assignment\n const draftGrade = scores?.score ? (scores?.score / 100) * maxPoints : 0\n const result = await api.httpsCallable?.('submitAssignmentToGoogleClassroomV2')?.({\n teacherId: owners[0],\n courseId,\n courseWorkId,\n userId: googleId,\n draftGrade,\n })\n\n return result\n } catch (error) {\n return { error: true, message: error.message }\n }\n }\n\n return {\n submitAssignmentToGoogleClassroom,\n }\n}\n","import { type GradingStandard } from '@core/services/add-grading-standard'\n\nimport { api } from '../api'\n\nexport const logGradingStandardLog = (data: {\n type: GradingStandard['type']\n level?: GradingStandard['level']\n courseId?: GradingStandard['courseId']\n}) => {\n if (data.courseId && data.type && data.level) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: data.type || 'custom',\n level: data.level,\n courseId: data.courseId,\n })\n }\n api.logEvent('logGradingStandard', data)\n}\n","// Event constants\nexport const ANALYTICS_EVENT_TYPES = {\n VOICE_SUCCESS: 'voice_success',\n VOICE_FAIL: 'voice_fail',\n RESPOND_CARD_SUCCESS: 'respond_card_success',\n RESPOND_CARD_FAIL: 'respond_card_fail',\n RESPOND_WRITE_CARD_SUCCESS: 'respond_write_card_success',\n RESPOND_WRITE_CARD_FAIL: 'respond_write_card_fail',\n RESPOND_WRITE_CARD_SUBMITTED: 'respond_write_card_submitted',\n RESPOND_WRITE_CARD_ERROR: 'respond_write_card_error',\n RESPOND_CARD_ERROR: 'respond_card_error',\n RESPOND_CARD_SUBMITTED: 'respond_card_submitted',\n RESPOND_FREE_PLAN: 'respond_free_plan',\n RESPOND_WRITE_FREE_PLAN: 'respond_write_free_plan',\n SUBMISSION: 'assignment_submitted',\n ASSIGNMENT_STARTED: 'assignment_started',\n CREATE_ASSIGNMENT: 'create_assignment',\n MC_SUCCESS: 'multiple_choice_success',\n MC_FAIL: 'multiple_choice_fail',\n MC_ERROR: 'multiple_choice_error',\n ACTFL_LEVEL: 'actfl_level',\n WIDA_LEVEL: 'wida_level',\n // New events\n VIEW_SCORES_MODAL: 'view_scores_modal',\n SHORT_ANSWER_SUCCESS: 'short_answer_success',\n SHORT_ANSWER_FAIL: 'short_answer_fail',\n SHORT_ANSWER_ERROR: 'short_answer_error',\n RETRY: 'retry',\n MESSAGE_SENT: 'message_sent',\n MESSAGE_ERROR: 'message_error',\n VIEW_DETAILS_CLICK: 'view_details_click',\n TABS_CLICK: 'tabs_click',\n VIEW_MEDIA: 'view_media',\n VIEW_SCORES: 'view_scores',\n VIEW_GRADING_METHOD: 'view_grading_method',\n VIEW_FEEDBACK: 'view_feedback',\n} as const\n","import { ANALYTICS_EVENT_TYPES } from '@core/constants/analytics.constants'\n\nimport { api } from '../api'\n\nexport const logOpenAssignment = (data = {}) => {\n api.logEvent('open_assignment', data)\n}\n\nexport const logOpenActivityPreview = (data = {}) => {\n api.logEvent('open_activity_preview', data)\n}\n\nexport const logSubmitAssignment = (data = {}) => {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.SUBMISSION,\n ...data,\n })\n api.logEvent(ANALYTICS_EVENT_TYPES.SUBMISSION, data)\n}\n\nexport const logCreateAssignment = (data = {}) => {\n // @ts-ignore\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT,\n ...data,\n })\n }\n api.logEvent(ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT, data)\n}\n\nexport const logStartAssignment = (data = {}) => {\n // @ts-ignore\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED,\n ...data,\n })\n }\n api.logEvent(ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED, data)\n}\n\nexport const logViewScoresModal = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_SCORES_MODAL, data)\n}\n\nexport const logViewMedia = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_MEDIA, data)\n}\n\nexport const logViewScores = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_SCORES, data)\n}\n\nexport const logViewGradingMethod = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_GRADING_METHOD, data)\n}\n\nexport const logViewFeedback = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_FEEDBACK, data)\n}\n","import { api } from '@core/lib/firebase/api'\n\nimport { type Score } from '../assignment.model'\n\nexport const defaultScore = (props: {\n owners: string[]\n courseId?: string\n userId: string\n googleClassroomUserId?: string\n}): Score => {\n const { serverTimestamp } = api.accessHelpers()\n\n const score = {\n progress: 0,\n score: 0,\n startDate: serverTimestamp(),\n status: 'IN_PROGRESS',\n submitted: false,\n cards: {},\n lastPlayed: serverTimestamp(),\n owners: props.owners,\n userId: props.userId,\n } as Score\n\n if (props.googleClassroomUserId) {\n score.googleClassroomUserId = props.googleClassroomUserId\n }\n\n if (props.courseId) {\n score.courseId = props.courseId\n }\n\n return score\n}\n","export const SCORES_PRACTICE_COLLECTION = 'users'\n\nexport const SCORES_PRACTICE_SUBCOLLECTION = 'practice'\n\nexport const refsScoresPractice = {\n practiceScores: (params: { userId: string; setId: string }) =>\n `${SCORES_PRACTICE_COLLECTION}/${params.userId}/${SCORES_PRACTICE_SUBCOLLECTION}/${params.setId}` as const,\n practiceScoreHistoryRefDoc: (params: { userId: string; setId: string; date: string }) =>\n `${SCORES_PRACTICE_COLLECTION}/${params.userId}/${SCORES_PRACTICE_SUBCOLLECTION}/${params.setId}/attempts/${params.date}` as const,\n}\n","import { withErrorHandler } from '@core/utils/error-handler'\nimport { api } from '@core/lib/firebase/api'\n\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { type Score } from '../assignment.model'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nasync function _createScore(params: {\n isAssignment: boolean\n activityId: string\n userId: string\n scoreData: Score\n}) {\n if (params.isAssignment) {\n const ref = refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n\n await api.httpsCallable?.('updateAssignmentGradebookStatus')?.({\n assignmentId: params.activityId,\n userId: params.userId,\n status: 'IN_PROGRESS',\n score: null,\n })\n\n await api.setDoc(ref, params.scoreData, { merge: true })\n\n return {\n id: params.userId,\n }\n } else {\n const ref = refsScoresPractice.practiceScores({\n userId: params.userId,\n setId: params.activityId,\n })\n\n await api.setDoc(ref, params.scoreData)\n\n return {\n id: params.userId,\n }\n }\n}\n\nexport const createScore = withErrorHandler(_createScore, 'createScore')\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\nimport { logStartAssignment } from '@core/lib/firebase/firebase-analytics'\n\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { type Score, type ScoreWithId } from '../assignment.model'\nimport { defaultScore } from '../utils/create-default-score'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nimport { createScore } from './create-score.service'\n\nexport async function getAssignmentScore({\n userId,\n assignment,\n googleClassroomUserId,\n}: {\n userId: string\n assignment: {\n id: string\n courseId?: string\n }\n googleClassroomUserId?: string\n}) {\n const path = refsAssignmentFiresotre.assignmentScores({\n id: assignment.id,\n userId,\n })\n\n const response = await api.getDoc<ScoreWithId>(path)\n\n if (response.data == null) {\n const newScore: Score = {\n ...defaultScore({\n owners: [userId],\n userId,\n courseId: assignment.courseId,\n googleClassroomUserId,\n }),\n assignmentId: assignment.id,\n }\n\n logStartAssignment({\n courseId: assignment.courseId,\n })\n\n const result = await createScore({\n activityId: assignment.id,\n userId,\n isAssignment: true,\n scoreData: newScore,\n })\n\n return {\n ...newScore,\n id: result.id,\n }\n }\n\n return response.data\n}\n\nexport async function getPracticeScore({ userId, setId }: { userId: string; setId: string }) {\n const path = refsScoresPractice.practiceScores({ userId, setId })\n\n const response = await api.getDoc<ScoreWithId>(path)\n\n if (response.data == null) {\n const newScore: Score = {\n ...defaultScore({\n owners: [userId],\n userId,\n }),\n setId,\n }\n\n const result = await createScore({\n activityId: setId,\n userId,\n isAssignment: false,\n scoreData: newScore,\n })\n\n return {\n ...newScore,\n id: result.id,\n }\n }\n\n return response.data\n}\n\nasync function _getScore(params: {\n userId: string\n activityId: string\n courseId?: string\n googleClassroomUserId?: string\n isAssignment: boolean\n}) {\n if (params.isAssignment) {\n return await getAssignmentScore({\n userId: params.userId,\n assignment: {\n id: params.activityId,\n courseId: params.courseId,\n },\n googleClassroomUserId: params.googleClassroomUserId,\n })\n } else {\n return await getPracticeScore({\n userId: params.userId,\n setId: params.activityId,\n })\n }\n}\n\nexport const getScore = withErrorHandler(_getScore, 'getScore')\n","import { type Score, type PageScore } from '../assignment.model'\n\nconst calculateScoreAndProgress = (\n scores: Score,\n cardsList: string[],\n weights: Record<string, number>,\n) => {\n const filteredScoreCards = Object.keys(scores?.cards || {}).reduce<Record<string, PageScore>>(\n (acc, cardId) => {\n const cardScores = scores?.cards?.[cardId]\n\n if (cardScores && !cardScores.media_area_opened) {\n acc[cardId] = cardScores\n }\n\n return acc\n },\n {},\n )\n\n const totalSetPoints = cardsList.reduce((acc, cardId) => {\n acc += weights?.[cardId] || 1\n\n return acc\n }, 0)\n\n const totalPointsAwarded = Object.keys(filteredScoreCards).reduce((acc, cardId) => {\n const cardScores = filteredScoreCards[cardId]\n\n if (cardScores?.completed || cardScores?.score || cardScores?.score === 0) {\n const score =\n cardScores?.score || cardScores?.score === 0 ? Number(cardScores?.score ?? 0) : null\n const weight = weights?.[cardId] || 1\n const fraction = (score ?? 0) / 100\n\n if (score || score === 0) {\n acc += weight * fraction\n } else {\n acc += weight\n }\n }\n\n return acc\n }, 0)\n\n const totalCompletedCards = Object.keys(filteredScoreCards).reduce((acc, cardId) => {\n const cardScores = filteredScoreCards[cardId]\n\n if (cardScores?.completed || cardScores?.score || cardScores?.score === 0) {\n acc += 1\n }\n\n return acc\n }, 0)\n\n const percent = totalPointsAwarded / totalSetPoints\n\n const score = Math.round(percent * 100)\n\n const progress = Math.round((totalCompletedCards / (cardsList.length || 1)) * 100)\n\n return { score, progress }\n}\n\nexport default calculateScoreAndProgress\n","// export async function updateScore(props: UpdateScore) {\n// const { userId, data, type } = props\n\nimport { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { type Score, type PageScore } from '../assignment.model'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nasync function _updateScore(params: {\n userId: string\n data: Partial<Score>\n isAssignment: boolean\n activityId: string\n}) {\n const path = params.isAssignment\n ? refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n : refsScoresPractice.practiceScores({\n setId: params.activityId,\n userId: params.userId,\n })\n\n await api.updateDoc(path, {\n ...params.data,\n })\n}\n\nexport const updateScore = withErrorHandler(_updateScore, 'updateScore')\n\nasync function _updateCardScore(params: {\n userId: string\n cardId: string\n isAssignment: boolean\n activityId: string\n updates: {\n cardScore: PageScore\n progress: number\n score: number\n }\n}) {\n const path = params.isAssignment\n ? refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n : refsScoresPractice.practiceScores({\n setId: params.activityId,\n userId: params.userId,\n })\n\n const updates = Object.keys(params.updates.cardScore).reduce<Record<string, unknown>>(\n (acc, key) => {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n acc[`cards.${params.cardId}.${key}`] = params.updates.cardScore[key]\n\n return acc\n },\n {},\n )\n\n if (params.updates.progress) {\n updates.progress = params.updates.progress\n }\n if (params.updates.score) {\n updates.score = params.updates.score\n }\n\n await api.updateDoc(path, {\n ...updates,\n })\n}\n\nexport const updateCardScore = withErrorHandler(_updateCardScore, 'updateCardScore')\n","import dayjs from 'dayjs'\nimport { api } from '@core/lib/firebase/api'\n\nimport { type PageScore, type Score } from '../assignment.model'\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nexport async function clearScore(params: {\n isAssignment: boolean\n cardId: string\n cardScores: PageScore\n userId: string\n activityId: string\n}) {\n const update: Partial<Score> = {\n [`cards.${params.cardId}`]: {\n attempts: (params.cardScores.attempts ?? 1) + 1,\n correct: params.cardScores.correct ?? 0,\n // save old score history\n history: [\n {\n ...params.cardScores,\n attempts: params.cardScores.attempts ?? 1,\n correct: params.cardScores.correct ?? 0,\n retryTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),\n history: null,\n },\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n ...(params.cardScores.history ?? []),\n ],\n },\n }\n\n const path = params.isAssignment\n ? refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n : refsScoresPractice.practiceScores({\n setId: params.activityId,\n userId: params.userId,\n })\n\n await api.updateDoc(path, update)\n\n return {\n update,\n activityId: params.activityId,\n }\n}\n\nexport async function clearScoreV2(params: {\n isAssignment: boolean\n cardId: string\n cardScores: PageScore\n userId: string\n activityId: string\n}) {\n const update: Partial<Score> = {\n [`cards.${params.cardId}`]: {\n ...params.cardScores,\n attempts: (params.cardScores.attempts ?? 1) + 1,\n correct: params.cardScores.correct ?? 0,\n history: [\n {\n ...params.cardScores,\n attempts: params.cardScores.attempts ?? 1,\n correct: params.cardScores.correct ?? 0,\n retryTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),\n history: null,\n },\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n ...(params.cardScores.history ?? []),\n ],\n },\n }\n\n const path = params.isAssignment\n ? refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n : refsScoresPractice.practiceScores({\n setId: params.activityId,\n userId: params.userId,\n })\n\n await api.updateDoc(path, update)\n\n return {\n update,\n activityId: params.activityId,\n }\n}\n","import { api } from '@core/lib/firebase/api'\nimport dayjs from 'dayjs'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { type Score } from '../assignment.model'\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport calculateScoreAndProgress from '../utils/calculateScoreAndProgress'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nasync function _submitAssignmentScore({\n cardIds,\n assignment,\n weights,\n userId,\n status,\n studentName,\n}: {\n cardIds: string[]\n assignment: {\n id: string\n name: string\n owners: string[]\n courseId: string\n courseWorkId: string\n isAssessment: boolean\n }\n weights: Record<string, number>\n userId: string\n status: Score['status']\n studentName: string\n}) {\n const { serverTimestamp } = api.accessHelpers()\n\n const path = refsAssignmentFiresotre.assignmentScores({ id: assignment.id, userId })\n\n const fieldsUpdated = {\n submitted: true,\n progress: 100,\n submissionDate: serverTimestamp(),\n status,\n } as Score\n\n if (assignment.isAssessment) {\n const result = await handleAssessment(\n assignment,\n userId,\n cardIds,\n weights,\n fieldsUpdated,\n studentName,\n )\n\n return result\n } else if (assignment.courseId) {\n await handleCourseAssignment(assignment, userId)\n }\n\n await api.updateDoc(path, { ...fieldsUpdated })\n\n return { success: true, fieldsUpdated }\n}\n\nexport const submitAssignmentScore = withErrorHandler(\n _submitAssignmentScore,\n 'submitAssignmentScore',\n)\n\nasync function handleAssessment(\n assignment: { id: string; name: string; owners: string[] },\n userId: string,\n cardIds: string[],\n weights: Record<string, number>,\n fieldsUpdated: Score,\n studentName: string,\n) {\n const path = refsAssignmentFiresotre.assignmentScores({ id: assignment.id, userId })\n\n const response = await api.getDoc<Score>(path)\n\n if (!response.data) {\n throw new Error('Score not found')\n }\n\n const { score: scoreCalculated } = calculateScoreAndProgress(response.data, cardIds, weights)\n\n await api.updateDoc(path, { score: scoreCalculated, status: 'PENDING_REVIEW' })\n\n await api.httpsCallable?.('submitAssessment')?.({\n assignmentId: assignment.id,\n assignmentTitle: assignment.name,\n userId,\n teacherId: assignment.owners[0],\n studentName,\n })\n\n fieldsUpdated.status = 'PENDING_REVIEW'\n\n return { success: true, fieldsUpdated }\n}\n\nasync function handleCourseAssignment(assignment: { id: string }, userId: string) {\n await api.httpsCallable?.('submitAssignmentV2')?.({\n assignmentId: assignment.id,\n userId,\n })\n}\n\nexport async function submitPracticeScore({\n setId,\n userId,\n scores,\n}: {\n userId: string\n setId: string\n scores: Score\n}) {\n const { serverTimestamp } = api.accessHelpers()\n\n // Create new scores object on the practice set subcollection /attempts\n const date = dayjs().format('YYYY-MM-DD-HH-mm')\n\n const ref = refsScoresPractice.practiceScoreHistoryRefDoc({ setId, userId, date })\n\n const fieldsUpdated = {\n ...scores,\n submitted: true,\n progress: 100,\n submissionDate: serverTimestamp(),\n status: 'SUBMITTED',\n } as Score\n\n await api.setDoc(ref, { ...fieldsUpdated })\n\n // clear the existing scores doc\n const refScores = refsScoresPractice.practiceScores({ userId, setId })\n\n await api.deleteDoc(refScores)\n\n return { success: true, fieldsUpdated }\n}\n","import { type QueryClient, useMutation, useQueries, useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\n\nimport { getCard } from './services/get-card.service'\nimport { type PageActivityWithId } from './card.model'\nimport { createCard, createCards } from './services/create-card.service'\n\nexport const cardsQueryKeys = {\n all: ['cards'],\n one: (params: { cardId: string }) => [...cardsQueryKeys.all, params.cardId],\n}\n\nexport function useCards({\n cardIds,\n enabled = true,\n asObject,\n}: {\n cardIds: string[]\n enabled: boolean\n asObject?: boolean\n}) {\n const queries = useQueries({\n queries: cardIds.map(cardId => ({\n enabled: enabled && cardIds.length > 0,\n queryKey: cardsQueryKeys.one({\n cardId,\n }),\n queryFn: () => getCard({ cardId }),\n })),\n })\n\n const cards = queries.map(query => query.data).filter(Boolean) as unknown as PageActivityWithId[]\n\n const cardsObject = useMemo(() => {\n if (!asObject) return null\n\n return cards.reduce<Record<string, PageActivityWithId>>((acc, card) => {\n acc[card.id] = card\n\n return acc\n }, {})\n }, [asObject, cards])\n\n return {\n cards,\n cardsObject,\n cardsQueries: queries,\n }\n}\n\nexport function useCreateCard() {\n const { queryClient } = useSpeakableApi()\n\n const mutationCreateCard = useMutation({\n mutationFn: createCard,\n onSuccess: cardCreated => {\n queryClient.invalidateQueries({ queryKey: cardsQueryKeys.one({ cardId: cardCreated.id }) })\n },\n })\n\n return {\n mutationCreateCard,\n }\n}\n\nexport function useCreateCards() {\n const mutationCreateCards = useMutation({\n mutationFn: createCards,\n })\n\n return {\n mutationCreateCards,\n }\n}\n\nexport function getCardFromCache({\n cardId,\n queryClient,\n}: {\n cardId: string\n queryClient: QueryClient\n}) {\n return queryClient.getQueryData<PageActivityWithId>(cardsQueryKeys.one({ cardId }))\n}\n\nexport function updateCardInCache({\n cardId,\n card,\n queryClient,\n}: {\n cardId: string\n card: PageActivityWithId | null\n queryClient: QueryClient\n}): void {\n queryClient.setQueryData(cardsQueryKeys.one({ cardId }), card)\n}\n\nexport function useGetCard({ cardId, enabled = true }: { cardId: string; enabled?: boolean }) {\n const query = useQuery({\n queryKey: cardsQueryKeys.one({ cardId }),\n queryFn: () => getCard({ cardId }),\n enabled: enabled && !!cardId,\n })\n\n return query\n}\n","import { type VerificationCardStatus } from './card.constants'\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport interface PageActivityWithId extends PageActivity {\n id: string\n}\n\nexport interface PageActivity {\n owners: string[]\n checked?: boolean\n completed?: boolean\n media_area_id?: string | null\n media_area_layout?: 'left' | 'right' | null\n media_mode?: 'single' | 'media_area' | 'none' | null\n media?: {\n type: 'image' | 'video'\n url: string\n } | null\n score?: number\n verificationStatus?: VerificationCardStatus\n native_text?: string\n repeat?: number\n language?: string | null\n image?: {\n path?: string | null\n url?: string\n }\n audio?: {\n path?: string | null\n url?: string\n } | null\n notes?: string\n difficulty?: string\n default_language?: string\n target_text?: string\n type: ActivityPageType\n grading_criteria?: string\n scoring_type?: string\n grading_method?: 'simple' | 'rubric' | 'manual' | 'standards_based'\n feedback_types?: string[]\n rubricId?: string\n prompt?: string\n title?: string\n passing_score?: number\n maxCharacters?: number\n answer?: string[]\n choices?: {\n value: string\n option: string\n }[]\n MCQType?: string\n multipleAttemptsAllowed?: boolean\n allowRetries?: boolean\n question?: string\n respondTime?: number\n hidePrompt?: boolean\n videoUrl?: string\n link?: string\n text?: string\n isListenAloud?: boolean\n embedCode?: string\n attempt?: number\n correct?: number\n autoGrade?: boolean\n points?: number\n shuffle?: boolean\n translation?: string\n includeAIContext?: boolean\n media_area_context_ref?: string | null\n standardId?: string\n target_proficiency_level?: string\n allowTTS?: boolean\n feedback_language?: string | null\n correct_answer?: string | null\n limit_attempts?: boolean\n max_attempts?: number\n rich_text?: string\n}\n\nexport const enum ActivityPageType {\n // DEFAULT = 'READ_REPEAT',\n READ_REPEAT = 'READ_REPEAT',\n READ_RESPOND = 'READ_RESPOND',\n FREE_RESPONSE = 'FREE_RESPONSE',\n REPEAT = 'REPEAT',\n RESPOND = 'RESPOND',\n RESPOND_WRITE = 'RESPOND_WRITE',\n MULTIPLE_CHOICE = 'MULTIPLE_CHOICE',\n MEDIA_PAGE = 'MEDIA_PAGE',\n SHORT_ANSWER = 'SHORT_ANSWER',\n}\n\nexport const RESPOND_PAGE_ACTIVITY_TYPES = [\n ActivityPageType.READ_RESPOND,\n ActivityPageType.RESPOND,\n ActivityPageType.RESPOND_WRITE,\n ActivityPageType.FREE_RESPONSE,\n]\n\nexport const MULTIPLE_CHOICE_PAGE_ACTIVITY_TYPES = [ActivityPageType.MULTIPLE_CHOICE]\n\nexport const REPEAT_PAGE_ACTIVITY_TYPES = [ActivityPageType.READ_REPEAT, ActivityPageType.REPEAT]\n\nexport const RESPOND_WRITE_PAGE_ACTIVITY_TYPES = [\n ActivityPageType.RESPOND_WRITE,\n ActivityPageType.FREE_RESPONSE,\n]\n\nexport const RESPOND_AUDIO_PAGE_ACTIVITY_TYPES = [\n ActivityPageType.RESPOND,\n ActivityPageType.READ_RESPOND,\n]\n","/* eslint-disable @typescript-eslint/naming-convention */\n\nexport enum FeedbackTypesCard {\n SuggestedResponse = 'suggested_response',\n Wida = 'wida',\n GrammarInsights = 'grammar_insights',\n Actfl = 'actfl',\n ProficiencyLevel = 'proficiency_level',\n}\n\nexport enum LeniencyCard {\n CONFIDENCE = 'confidence',\n EASY = 'easy',\n NORMAL = 'normal',\n HARD = 'hard',\n}\n\nexport const LENIENCY_OPTIONS = [\n {\n label: 'Build Confidence - most lenient',\n value: LeniencyCard.CONFIDENCE,\n },\n {\n label: 'Very Lenient',\n value: LeniencyCard.EASY,\n },\n {\n label: 'Normal',\n value: LeniencyCard.NORMAL,\n },\n {\n label: 'No leniency - most strict',\n value: LeniencyCard.HARD,\n },\n]\n\nexport const STUDENT_LEVELS_OPTIONS = [\n {\n label: 'Beginner',\n description: 'Beginner Level: Just starting out. Can say a few basic words and phrases.',\n value: 'beginner',\n },\n {\n label: 'Elementary',\n description:\n 'Elementary Level: Can understand simple sentences and have very basic conversations.',\n value: 'elementary',\n },\n {\n label: 'Intermediate',\n description: 'Intermediate Level: Can talk about everyday topics and handle common situations.',\n value: 'intermediate',\n },\n {\n label: 'Advanced',\n description: 'Advanced Level: Can speak and understand with ease, and explain ideas clearly.',\n value: 'advanced',\n },\n {\n label: 'Fluent',\n description:\n 'Fluent Level: Speaks naturally and easily. Can use the language in work or school settings.',\n value: 'fluent',\n },\n {\n label: 'Native-like',\n description:\n 'Native-like Level: Understands and speaks like a native. Can discuss complex ideas accurately.',\n value: 'nativeLike',\n },\n]\n\nexport const BASE_RESPOND_FIELD_VALUES = {\n title: '',\n allowRetries: true,\n respondTime: 180,\n maxCharacters: 1000,\n}\n\nexport const BASE_REPEAT_FIELD_VALUES = {\n repeat: 1,\n}\n\nexport const BASE_MULTIPLE_CHOICE_FIELD_VALUES = {\n MCQType: 'single',\n answer: ['A'],\n choices: [\n { option: 'A', value: 'Option A' },\n { option: 'B', value: 'Option B' },\n { option: 'C', value: 'Option C' },\n ],\n}\n\nexport enum VerificationCardStatus {\n VERIFIED = 'VERIFIED',\n WARNING = 'WARNING',\n NOT_RECOMMENDED = 'NOT_RECOMMENDED',\n NOT_WORKING = 'NOT_WORKING',\n NOT_CHECKED = 'NOT_CHECKED',\n}\n\nconst CARDS_COLLECTION = 'flashcards'\n\nexport type RefsCardsFiresotre = `${typeof CARDS_COLLECTION}/${string}`\n\nexport const refsCardsFiresotre = {\n allCards: CARDS_COLLECTION,\n card: (id: string) => `${CARDS_COLLECTION}/${id}` as const,\n}\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { ActivityPageType, type PageActivityWithId } from '../card.model'\nimport { refsCardsFiresotre } from '../card.constants'\n\nasync function _getCard(params: { cardId: string }) {\n const ref = refsCardsFiresotre.card(params.cardId)\n\n const response = await api.getDoc<PageActivityWithId>(ref)\n\n if (!response.data) return null\n\n const type = response.data.type || ActivityPageType.READ_REPEAT\n\n const cardsMapped = {\n ...response.data,\n type: type,\n }\n\n return cardsMapped\n}\n\nexport const getCard = withErrorHandler(_getCard, 'getCard')\n","import { v4 } from 'uuid'\nimport { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { ActivityPageType, type PageActivityWithId, type PageActivity } from '../card.model'\nimport { refsCardsFiresotre } from '../card.constants'\n\nimport { getVerificationStatus } from './get-card-verification-status.service'\n\nasync function _createCard({ data }: { data: Partial<PageActivity> }) {\n const response = await api.addDoc(refsCardsFiresotre.allCards, data)\n\n return response\n}\n\nexport const createCard = withErrorHandler(_createCard, 'createCard')\n\nasync function _createCards({ cards }: { cards: PageActivity[] }) {\n const { writeBatch, doc } = api.accessHelpers()\n\n const batch = writeBatch()\n\n const cardsWithId = []\n\n for (const card of cards) {\n const cardId = v4()\n\n const ref = doc(refsCardsFiresotre.card(cardId))\n\n const newCardObject = {\n ...card,\n id: cardId,\n }\n\n if (card.type === ActivityPageType.READ_REPEAT && card.target_text && card.language) {\n const verificationStatus = await getVerificationStatus(card.target_text, card.language)\n\n newCardObject.verificationStatus = verificationStatus || null\n }\n cardsWithId.push(newCardObject)\n batch.set(ref, newCardObject)\n }\n\n await batch.commit()\n\n return cardsWithId satisfies PageActivityWithId[]\n}\n\nexport const createCards = withErrorHandler(_createCards, 'createCards')\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\nimport { sha1 } from 'js-sha1'\n\nexport const purify = (word: string) => {\n return word\n .normalize('NFD')\n .replace(/\\/([^\" \"]*)/g, '') // removes word after slash to space el/la --> el\n .replace(/\\([^()]*\\)/g, '') // removes word parenthesis\n .replace(/([^()]*)/g, '') //removes chinese parenthesis\n .replace(/[\\u0300-\\u036f]/g, '') // removes diacritics\n .replace(/[-]/g, ' ') // removes hyphens\n .replace(/[.,/#!¡¿?؟。,.?$%^&*;:{}=\\-_`~()’'…\\s]/g, '') // removes punctuation\n .replace(/\\s\\s+/g, ' ') //Removes all whitespace\n .toLowerCase()\n .trim()\n}\n\nexport const cleanString = (words: string) => {\n const splitWords = words?.split('+')\n\n if (splitWords && splitWords.length === 1) {\n const newWord = purify(words)\n\n return newWord\n } else if (splitWords && splitWords.length > 1) {\n const split = splitWords.map(w => purify(w))\n\n return split\n } else {\n return ''\n }\n}\n\nexport const getWordHash = (word: string, language: string) => {\n const cleanedWord = cleanString(word)\n const wordHash = sha1(`${language}-${cleanedWord as string}`)\n\n console.log('wordHash core library', wordHash)\n\n return wordHash\n}\n\nexport function getPhraseLength(phrase: string, input?: string) {\n if (Array.isArray(phrase) && phrase.includes(input)) {\n return phrase[phrase.indexOf(input)].split(' ').length as number\n } else {\n return phrase ? phrase.split(' ').length : (0 as number)\n }\n}\n","/* eslint-disable @typescript-eslint/restrict-plus-operands */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { getWordHash } from '@core/utils/text-utils'\nimport { api } from '@core/lib/firebase/api'\n\nimport { VerificationCardStatus } from '../card.constants'\n\nconst charactarLanguages = ['zh', 'ja', 'ko']\n\nexport const getVerificationStatus = async (target_text: string, language: string) => {\n if (target_text?.length < 3 && !charactarLanguages.includes(language)) {\n return VerificationCardStatus.NOT_RECOMMENDED\n }\n const hash = getWordHash(target_text, language)\n const response = await api.getDoc<any>(`checked-pronunciations/${hash}`)\n\n try {\n if (response.data) {\n return processRecord(response.data)\n } else {\n return VerificationCardStatus.NOT_CHECKED\n }\n } catch (e) {\n return VerificationCardStatus.NOT_CHECKED\n }\n}\n\nconst processRecord = (data: any) => {\n const { pronunciations = 0, fails = 0 } = data\n const attempts = pronunciations + fails\n const successRate = attempts > 0 ? (pronunciations / attempts) * 100 : 0\n let newStatus = null\n\n if (attempts < 6) {\n return VerificationCardStatus.NOT_CHECKED\n }\n if (successRate > 25) {\n // console.log('Verified')\n newStatus = VerificationCardStatus.VERIFIED\n } else if (successRate > 10) {\n // console.log('Warning')\n newStatus = VerificationCardStatus.WARNING\n } else if (fails > 20 && successRate < 10 && pronunciations > 1) {\n // console.log('Not recommended for use')\n newStatus = VerificationCardStatus.NOT_RECOMMENDED\n } else if (pronunciations === 0 && fails > 20) {\n // console.log('does not work')\n newStatus = VerificationCardStatus.NOT_WORKING\n } else {\n // console.log('no data - must be checked')\n newStatus = VerificationCardStatus.NOT_CHECKED\n }\n\n return newStatus\n}\n","import { createCards } from './services/create-card.service'\nimport { createCard } from './services/create-card.service'\nimport { getCard } from './services/get-card.service'\n\nexport const createCardRepo = () => {\n return {\n createCard: createCard,\n createCards: createCards,\n getCard: getCard,\n }\n}\n","import {\n ActivityPageType,\n REPEAT_PAGE_ACTIVITY_TYPES,\n MULTIPLE_CHOICE_PAGE_ACTIVITY_TYPES,\n RESPOND_PAGE_ACTIVITY_TYPES,\n RESPOND_WRITE_PAGE_ACTIVITY_TYPES,\n RESPOND_AUDIO_PAGE_ACTIVITY_TYPES,\n} from '../card.model'\n\nexport function checkIsRepeatPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return REPEAT_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport function checkIsMCPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return MULTIPLE_CHOICE_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport function checkIsRespondPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return RESPOND_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport function checkIsRespondWrittenPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return RESPOND_WRITE_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport function checkIsRespondAudioPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return RESPOND_AUDIO_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport const checkIsMediaPage = (cardType: ActivityPageType | undefined) => {\n if (cardType === undefined) return false\n\n return cardType === ActivityPageType.MEDIA_PAGE\n}\n\nexport const checkIsShortAnswerPage = (cardType: ActivityPageType | undefined) => {\n if (cardType === undefined) return false\n\n return cardType === ActivityPageType.SHORT_ANSWER\n}\n\nexport const checkTypePageActivity = (cardType: ActivityPageType | undefined) => {\n const isRespondAudio = checkIsRespondAudioPage(cardType)\n const isRespondWritten = checkIsRespondWrittenPage(cardType)\n\n const isRespond = checkIsRespondPage(cardType)\n const isMC = checkIsMCPage(cardType)\n const isRepeat = checkIsRepeatPage(cardType)\n const isMediaPage = checkIsMediaPage(cardType)\n\n const isShortAnswer = checkIsShortAnswerPage(cardType)\n\n const isNoOneOfThem = !isRespond && !isMC && !isRepeat && !isMediaPage && !isShortAnswer\n\n if (isNoOneOfThem) {\n return {\n isRespondAudio: false,\n isRespondWritten: false,\n isRespond: false,\n isMC: false,\n isRepeat: true,\n isMediaPage: false,\n isShortAnswer: false,\n hasSomeType: false,\n }\n }\n\n return {\n isRespondAudio,\n isRespondWritten,\n isRespond,\n isMC,\n isRepeat,\n isMediaPage,\n isShortAnswer,\n hasSomeType: true,\n }\n}\n","import { type PageActivityWithId } from '../card.model'\n\nimport { checkTypePageActivity } from './check-page-type'\n\nfunction extractTextFromRichText(richText: string | undefined): string {\n if (!richText) return ''\n\n return richText\n .replace(/<[^>]*>/g, '')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .trim()\n}\n\nexport function getPagePrompt(card: PageActivityWithId | undefined) {\n if (!card) return { has: false, text: '', rich_text: '', isTextEqualToRichText: false }\n\n const { isMC, isRepeat, isRespond, isShortAnswer } = checkTypePageActivity(card?.type)\n const hidePrompt = card?.hidePrompt === true\n\n const createReturnObject = (text: string | undefined, richText: string | undefined) => {\n const plainText = text || ''\n const richTextPlain = extractTextFromRichText(richText)\n\n return {\n has: true,\n text: plainText,\n rich_text: richText || '',\n isTextEqualToRichText: plainText.trim() === richTextPlain.trim(),\n }\n }\n\n if (isRepeat) {\n return createReturnObject(card?.target_text, card?.rich_text)\n }\n\n if (isRespond && !hidePrompt) {\n return createReturnObject(card?.prompt, card?.rich_text)\n }\n\n if (isMC) {\n return createReturnObject(card?.question, card?.rich_text)\n }\n\n if (isShortAnswer && !hidePrompt) {\n return createReturnObject(card?.prompt, card?.rich_text)\n }\n\n return {\n has: false,\n text: '',\n rich_text: '',\n isTextEqualToRichText: false,\n }\n}\n","import { type Score } from '@core/domains/assignment'\n\nexport const getTotalCompletedCards = (pageScores: Score['cards'] | undefined) => {\n return Object.values(pageScores ?? {}).reduce((acc, cardScore) => {\n if (\n (cardScore.completed ?? cardScore.score ?? cardScore.score === 0) &&\n !cardScore.media_area_opened\n ) {\n acc++\n }\n\n return acc\n }, 0)\n}\n","import { type ActivityPageType } from '../card.model'\n\nimport { checkTypePageActivity } from './check-page-type'\n\nconst labels = {\n repeat: {\n short: 'Repeat',\n long: 'Listen & Repeat',\n },\n mc: {\n short: 'Multiple Choice',\n long: 'Multiple Choice',\n },\n mediaPage: {\n short: 'Media Page',\n long: 'Media Page',\n },\n shortAnswer: {\n short: 'Short Answer',\n long: 'Short Answer',\n },\n respondWritten: {\n short: 'Open Response',\n long: 'Written Open Response',\n },\n respondAudio: {\n short: 'Open Response',\n long: 'Spoken Open Response',\n },\n}\n\nexport const getLabelPage = (pageType: ActivityPageType | undefined) => {\n if (!pageType) {\n return {\n short: '',\n long: '',\n }\n }\n\n const { isRepeat, isMC, isMediaPage, isShortAnswer, isRespondWritten, isRespondAudio } =\n checkTypePageActivity(pageType)\n\n if (isRepeat) {\n return labels.repeat\n }\n\n if (isMC) {\n return labels.mc\n }\n\n if (isMediaPage) {\n return labels.mediaPage\n }\n\n if (isShortAnswer) {\n return labels.shortAnswer\n }\n\n if (isRespondWritten) {\n return labels.respondWritten\n }\n\n if (isRespondAudio) {\n return labels.respondAudio\n }\n\n return {\n short: '',\n long: '',\n }\n}\n","import { type PageActivityWithId } from '../card.model'\n\nimport { checkTypePageActivity } from './check-page-type'\n\nexport function getPageMediaData(page: PageActivityWithId) {\n const direction = page.media_area_layout ?? 'left'\n const { isMediaPage } = checkTypePageActivity(page.type)\n const mode = (page.media_mode ?? page.media_area_id) ? 'media_area' : null\n const singleMedia = getSingleMediaPageData(page)\n\n const hasMediaData = isMediaPage && singleMedia !== undefined\n\n return {\n direction,\n mode,\n singleMedia,\n isMediaPage,\n hasMediaData,\n }\n}\n\nexport function getSingleMediaPageData(page: PageActivityWithId) {\n const isSingleMode = page.media_mode === 'single'\n\n if (!isSingleMode || !page.media) return undefined\n\n const media = {\n type: page.media.type,\n content: page.media.url,\n }\n\n return {\n ...media,\n rawObject: page.media,\n }\n}\n","import { type QueryClient, useQuery } from '@tanstack/react-query'\n\nimport { getSet } from './services/get-set.service'\nimport { type SetWithId } from './set.model'\n\nexport const setsQueryKeys = {\n all: ['sets'],\n one: (params: { setId: string }) => [...setsQueryKeys.all, params.setId],\n}\n\nexport const useSet = ({ setId, enabled }: { setId: string; enabled?: boolean }) => {\n return useQuery({\n queryKey: setsQueryKeys.one({ setId }),\n queryFn: () => getSet({ setId }),\n enabled: setId !== undefined && setId !== '' && enabled,\n })\n}\n\nexport function getSetFromCache({\n setId,\n queryClient,\n}: {\n setId: string | undefined\n queryClient: QueryClient\n}) {\n if (!setId) return null\n\n return queryClient.getQueryData<SetWithId>(setsQueryKeys.one({ setId }))\n}\n\nexport function updateSetInCache({\n set,\n queryClient,\n}: {\n set: SetWithId\n queryClient: QueryClient\n}) {\n const { id, ...setData } = set\n\n queryClient.setQueryData(setsQueryKeys.one({ setId: id }), setData)\n}\n","const SETS_COLLECTION = 'sets'\n\nexport type RefsSetsFirestore = `${typeof SETS_COLLECTION}/${string}`\n\nexport const refsSetsFirestore = {\n allSets: SETS_COLLECTION,\n set: (id: string) => `${SETS_COLLECTION}/${id}` as const,\n}\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { refsSetsFirestore } from '../set.constants'\nimport { type SetWithId } from '../set.model'\n\nasync function _getSet({ setId }: { setId: string }) {\n const response = await api.getDoc<SetWithId>(refsSetsFirestore.set(setId))\n\n return response.data\n}\n\nexport const getSet = withErrorHandler(_getSet, 'getSet')\n","import { getSet } from './services/get-set.service'\n\nexport const createSetRepo = () => {\n return {\n getSet,\n }\n}\n","/**\n * Configuration thresholds for hallucination detection\n */\nconst HALLUCINATION_THRESHOLDS = {\n // Short repeats\n MIN_CONSECUTIVE_REPEATS: 3,\n MIN_WORDS_FOR_RATIO_CHECK: 10,\n MAX_UNIQUE_WORDS_FOR_RATIO: 3,\n MIN_REPETITION_RATIO: 3,\n\n // Phrase repeats\n MIN_SENTENCE_LENGTH: 10,\n MIN_CONSECUTIVE_SIMILAR_SENTENCES: 2,\n MIN_SENTENCES_FOR_DUPLICATE_CHECK: 3,\n\n // Cyclic patterns\n MIN_CYCLE_LENGTH: 20,\n MIN_CYCLE_REPEATS: 3,\n\n // Entropy detection\n MIN_LENGTH_FOR_ENTROPY_CHECK: 50,\n MAX_ENTROPY_THRESHOLD: 2.5, // bits per character\n\n // Similarity\n SENTENCE_SIMILARITY_THRESHOLD: 0.8,\n SEGMENT_SIMILARITY_THRESHOLD: 0.85,\n} as const\n\n/**\n * Result of hallucination detection with details\n */\nexport interface HallucinationDetectionResult {\n isHallucination: boolean\n reason?: string\n confidence?: number\n}\n\n/**\n * Detects if a transcript contains hallucinated repetitive patterns\n * that Whisper sometimes produces when no clear audio is detected.\n *\n * Common patterns:\n * - \"no, no, no, no...\"\n * - \"yes I did it! yes I did it!...\"\n * - \"Okay, here's what me thinking. Me no like...\"\n *\n * @param transcript - The transcript text to analyze\n * @returns true if hallucination is detected, false otherwise\n */\nexport function detectTranscriptHallucination(transcript: string): boolean {\n const result = detectTranscriptHallucinationWithDetails(transcript)\n\n return result.isHallucination\n}\n\n/**\n * Detects transcript hallucination and provides details about why\n *\n * @param transcript - The transcript text to analyze\n * @returns Detection result with reason and confidence\n */\nexport function detectTranscriptHallucinationWithDetails(\n transcript: string,\n): HallucinationDetectionResult {\n if (!transcript || transcript.trim().length === 0) {\n return { isHallucination: false }\n }\n\n const text = transcript.trim()\n\n // Skip very short transcripts (less than 10 characters)\n if (text.length < 10) {\n return { isHallucination: false }\n }\n\n // 1. Check for very short repeated words/phrases (like \"no, no, no, no\")\n const shortRepeats = detectShortRepeats(text)\n\n if (shortRepeats) {\n return {\n isHallucination: true,\n reason: 'Detected repeated short words or phrases',\n confidence: 0.9,\n }\n }\n\n // 2. Check for repeated sentences or long phrases\n const phraseRepeats = detectPhraseRepeats(text)\n\n if (phraseRepeats) {\n return {\n isHallucination: true,\n reason: 'Detected repeated sentences or phrases',\n confidence: 0.85,\n }\n }\n\n // 3. Check for cyclic patterns (ABC ABC ABC)\n const cyclicRepeats = detectCyclicPattern(text)\n\n if (cyclicRepeats) {\n return {\n isHallucination: true,\n reason: 'Detected cyclic repetition pattern',\n confidence: 0.8,\n }\n }\n\n // 4. Check for low entropy (gibberish or very repetitive text)\n if (text.length >= HALLUCINATION_THRESHOLDS.MIN_LENGTH_FOR_ENTROPY_CHECK) {\n const entropy = calculateEntropy(text)\n\n if (entropy < HALLUCINATION_THRESHOLDS.MAX_ENTROPY_THRESHOLD) {\n return {\n isHallucination: true,\n reason: 'Detected low entropy (likely gibberish or excessive repetition)',\n confidence: 0.75,\n }\n }\n }\n\n return { isHallucination: false }\n}\n\n/**\n * Detects short repeated words like \"no, no, no\" or \"yes, yes, yes\"\n */\nfunction detectShortRepeats(text: string): boolean {\n // Split by punctuation and whitespace\n const words = text\n .toLowerCase()\n .split(/[\\s,;.!?]+/)\n .filter(w => w.length > 0)\n\n if (words.length < 4) return false\n\n // Check for sequences of consecutive identical words\n let repeatCount = 1\n\n for (let i = 1; i < words.length; i++) {\n if (words[i] === words[i - 1]) {\n repeatCount++\n if (repeatCount >= HALLUCINATION_THRESHOLDS.MIN_CONSECUTIVE_REPEATS) {\n return true\n }\n } else {\n repeatCount = 1\n }\n }\n\n // Check if majority of text is just a few words repeated\n const uniqueWords = new Set(words)\n const repetitionRatio = words.length / uniqueWords.size\n\n if (\n words.length >= HALLUCINATION_THRESHOLDS.MIN_WORDS_FOR_RATIO_CHECK &&\n uniqueWords.size <= HALLUCINATION_THRESHOLDS.MAX_UNIQUE_WORDS_FOR_RATIO &&\n repetitionRatio >= HALLUCINATION_THRESHOLDS.MIN_REPETITION_RATIO\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Detects repeated sentences or phrases\n */\nfunction detectPhraseRepeats(text: string): boolean {\n // Split into sentences\n const sentences = text\n .split(/[.!?]+/)\n .map(s => s.trim().toLowerCase())\n .filter(s => s.length > HALLUCINATION_THRESHOLDS.MIN_SENTENCE_LENGTH)\n\n if (sentences.length < 2) return false\n\n // Check for consecutive sentence repetition\n for (let i = 0; i < sentences.length - 1; i++) {\n let consecutiveRepeats = 1\n\n for (let j = i + 1; j < sentences.length; j++) {\n if (isSimilarSentence(sentences[i], sentences[j])) {\n consecutiveRepeats++\n } else {\n break\n }\n }\n\n if (consecutiveRepeats >= HALLUCINATION_THRESHOLDS.MIN_CONSECUTIVE_SIMILAR_SENTENCES) {\n return true\n }\n }\n\n // Check if majority of sentences are duplicates\n const uniqueSentences = new Set(sentences)\n\n if (\n sentences.length >= HALLUCINATION_THRESHOLDS.MIN_SENTENCES_FOR_DUPLICATE_CHECK &&\n uniqueSentences.size === 1\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Check if two sentences are similar (allowing for minor variations)\n */\nfunction isSimilarSentence(\n s1: string,\n s2: string,\n threshold: number = HALLUCINATION_THRESHOLDS.SENTENCE_SIMILARITY_THRESHOLD,\n): boolean {\n // Exact match\n if (s1 === s2) return true\n\n // Remove extra spaces and compare\n const normalized1 = s1.replace(/\\s+/g, ' ').trim()\n const normalized2 = s2.replace(/\\s+/g, ' ').trim()\n\n if (normalized1 === normalized2) return true\n\n // Check similarity by word overlap (Sørensen-Dice coefficient)\n const words1 = normalized1.split(/\\s+/)\n const words2 = normalized2.split(/\\s+/)\n\n // If lengths differ significantly, not similar\n if (Math.abs(words1.length - words2.length) > 2) return false\n\n // Calculate word overlap using Sørensen-Dice coefficient\n const set1 = new Set(words1)\n const set2 = new Set(words2)\n const intersection = new Set([...set1].filter(w => set2.has(w)))\n\n const similarity = (intersection.size * 2) / (set1.size + set2.size)\n\n return similarity >= threshold\n}\n\n/**\n * Detects cyclic repetition patterns (e.g., \"ABC ABC ABC\")\n * Optimized to check fewer cycle lengths and use more appropriate similarity metric\n */\nfunction detectCyclicPattern(text: string): boolean {\n const normalized = text.toLowerCase().replace(/\\s+/g, ' ').trim()\n const length = normalized.length\n\n // Try different cycle lengths\n const minCycleLength = HALLUCINATION_THRESHOLDS.MIN_CYCLE_LENGTH\n const maxCycleLength = Math.floor(length / 2)\n\n if (maxCycleLength < minCycleLength) return false\n\n // Optimize: Check fewer cycle lengths (every 5 chars instead of every char)\n const step = 5\n\n for (let cycleLen = minCycleLength; cycleLen <= maxCycleLength; cycleLen += step) {\n const pattern = normalized.substring(0, cycleLen)\n let matchCount = 0\n let pos = 0\n\n // Count how many times this pattern repeats\n while (pos < length) {\n const segment = normalized.substring(pos, pos + cycleLen)\n\n if (segment.length < cycleLen) {\n // Handle the last partial segment\n const partialMatch = pattern.startsWith(segment)\n\n if (partialMatch && matchCount > 0) {\n matchCount++\n }\n break\n }\n\n // Use character-level similarity for segments (not word-level)\n if (segment === pattern || isSegmentSimilar(segment, pattern)) {\n matchCount++\n pos += cycleLen\n } else {\n break\n }\n }\n\n if (matchCount >= HALLUCINATION_THRESHOLDS.MIN_CYCLE_REPEATS) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Checks if two text segments are similar using character-level comparison\n * More appropriate than word-level comparison for arbitrary text segments\n */\nfunction isSegmentSimilar(s1: string, s2: string): boolean {\n if (s1 === s2) return true\n if (s1.length !== s2.length) return false\n\n // Calculate character-level similarity (Levenshtein-like but simpler)\n let matches = 0\n const minLength = Math.min(s1.length, s2.length)\n\n for (let i = 0; i < minLength; i++) {\n if (s1[i] === s2[i]) {\n matches++\n }\n }\n\n const similarity = matches / minLength\n\n return similarity >= HALLUCINATION_THRESHOLDS.SEGMENT_SIMILARITY_THRESHOLD\n}\n\n/**\n * Calculates Shannon entropy of text (in bits per character)\n * Lower entropy indicates more repetitive or predictable text\n *\n * @param text - Text to analyze\n * @returns Entropy value (typically 0-8 bits for text)\n */\nfunction calculateEntropy(text: string): number {\n if (!text || text.length === 0) {\n return 0\n }\n\n // Count character frequencies\n const frequencies = new Map<string, number>()\n\n for (const char of text.toLowerCase()) {\n frequencies.set(char, (frequencies.get(char) || 0) + 1)\n }\n\n // Calculate Shannon entropy: H = -Σ(p(x) * log2(p(x)))\n let entropy = 0\n const length = text.length\n\n for (const count of frequencies.values()) {\n const probability = count / length\n\n entropy -= probability * Math.log2(probability)\n }\n\n return entropy\n}\n\n/**\n * Cleans a transcript by detecting and removing hallucinations\n * Returns empty string if hallucination detected, otherwise returns original transcript\n */\nexport function cleanHallucinatedTranscript(transcript: string): string {\n const result = detectTranscriptHallucinationWithDetails(transcript)\n\n if (result.isHallucination) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Hallucinated transcript detected and removed:',\n transcript.substring(0, 100),\n `\\nReason: ${result.reason ?? 'Unknown'}`,\n `Confidence: ${String(result.confidence ?? 'Unknown')}`,\n )\n\n return ''\n }\n\n return transcript\n}\n","import { api } from '@core/lib/firebase/api'\n\nimport { cleanHallucinatedTranscript } from './detect-transcript-hallucionation'\n\nexport async function getTranscript(\n model: 'gemini' | 'assemblyai' | 'whisper',\n args: {\n language: string\n audioUrl: string\n prompt?: string\n },\n cleanHallucinations = true,\n) {\n const getGeminiTranscript = api.httpsCallable?.('getGeminiTranscript')\n const getAssemblyAITranscript = api.httpsCallable?.('transcribeAssemblyAIAudio')\n const getWhisperTranscript = api.httpsCallable?.('transcribeAudio')\n\n if (model === 'whisper') {\n try {\n const { data } = (await getWhisperTranscript?.({\n audioUrl: args.audioUrl,\n language: args.language,\n })) as {\n data: string\n }\n\n return cleanHallucinations ? cleanHallucinatedTranscript(data) : data\n } catch (error) {\n console.error('Error getting transcript from Whisper:', error)\n throw error\n }\n }\n\n if (model === 'gemini') {\n try {\n const { data } = (await getGeminiTranscript?.({\n audioUrl: args.audioUrl,\n targetLanguage: args.language,\n prompt: args.prompt,\n })) as {\n data: {\n transcript: string\n }\n }\n\n return cleanHallucinations ? cleanHallucinatedTranscript(data.transcript) : data.transcript\n } catch (error) {\n console.error('Error getting transcript from Gemini:', error)\n throw error\n }\n }\n\n if (model === 'assemblyai') {\n try {\n const response = (await getAssemblyAITranscript?.({\n audioUrl: args.audioUrl,\n language: args.language,\n })) as {\n data: string\n }\n\n return cleanHallucinations ? cleanHallucinatedTranscript(response.data) : response.data\n } catch (error) {\n console.error('Error getting transcript from AssemblyAI:', error)\n throw error\n }\n }\n\n return null\n}\n\nexport async function getTranscriptCycle(args: {\n audioUrl: string\n language: string\n prompt: string\n}) {\n const models = ['whisper', 'gemini', 'assemblyai'] as const\n let transcript = ''\n let lastError: unknown = null\n\n // Try each model in order until we get a successful transcript\n for (const model of models) {\n try {\n const transcriptResult = await getTranscript(model, args, false)\n const rawTranscript = transcriptResult || ''\n\n transcript = cleanHallucinatedTranscript(rawTranscript)\n\n // If we got a non-empty transcript, we're done\n if (transcript !== '') {\n console.log(`Successfully got transcript from ${model}`)\n break\n }\n\n console.warn(`${model} returned empty transcript, trying next model`)\n } catch (e) {\n console.error(`Error with ${model} transcript:`, e)\n lastError = e\n }\n }\n\n // If all models failed or returned empty strings, show error\n if (transcript === '') {\n console.error('All transcript models failed or returned empty', lastError)\n\n return {\n transcript: '',\n success: false,\n }\n }\n\n return {\n transcript,\n success: true,\n }\n}\n","{\n \"af\": \"Afrikaans\",\n \"sq\": \"Albanian\",\n \"am\": \"Amharic\",\n \"ar\": \"Arabic\",\n \"hy\": \"Armenian\",\n \"az\": \"Azerbaijani\",\n \"eu\": \"Basque\",\n \"be\": \"Belarusian\",\n \"bn\": \"Bengali\",\n \"bs\": \"Bosnian\",\n \"bg\": \"Bulgarian\",\n \"ca\": \"Catalan\",\n \"ceb\": \"Cebuano\",\n \"zh\": \"Chinese\",\n \"co\": \"Corsican\",\n \"hr\": \"Croatian\",\n \"cs\": \"Czech\",\n \"da\": \"Danish\",\n \"nl\": \"Dutch\",\n \"en\": \"English\",\n \"eo\": \"Esperanto\",\n \"et\": \"Estonian\",\n \"fi\": \"Finnish\",\n \"fr\": \"French\",\n \"fy\": \"Frisian\",\n \"gl\": \"Galician\",\n \"ka\": \"Georgian\",\n \"de\": \"German\",\n \"el\": \"Greek\",\n \"gu\": \"Gujarati\",\n \"ht\": \"Haitian Creole\",\n \"ha\": \"Hausa\",\n \"haw\": \"Hawaiian\",\n \"he\": \"Hebrew\",\n \"hi\": \"Hindi\",\n \"hmn\": \"Hmong\",\n \"hu\": \"Hungarian\",\n \"is\": \"Icelandic\",\n \"ig\": \"Igbo\",\n \"id\": \"Indonesian\",\n \"ga\": \"Irish\",\n \"it\": \"Italian\",\n \"ja\": \"Japanese\",\n \"jv\": \"Javanese\",\n \"kn\": \"Kannada\",\n \"kk\": \"Kazakh\",\n \"km\": \"Khmer\",\n \"ko\": \"Korean\",\n \"ku\": \"Kurdish\",\n \"ky\": \"Kyrgyz\",\n \"lo\": \"Lao\",\n \"la\": \"Latin\",\n \"lv\": \"Latvian\",\n \"lt\": \"Lithuanian\",\n \"lb\": \"Luxembourgish\",\n \"mk\": \"Macedonian\",\n \"mg\": \"Malagasy\",\n \"ms\": \"Malay\",\n \"ml\": \"Malayalam\",\n \"mt\": \"Maltese\",\n \"mi\": \"Maori\",\n \"mr\": \"Marathi\",\n \"mn\": \"Mongolian\",\n \"my\": \"Myanmar (Burmese)\",\n \"ne\": \"Nepali\",\n \"no\": \"Norwegian\",\n \"ny\": \"Nyanja (Chichewa)\",\n \"ps\": \"Pashto\",\n \"fa\": \"Persian\",\n \"pl\": \"Polish\",\n \"pt\": \"Portuguese\",\n \"pa\": \"Punjabi\",\n \"ro\": \"Romanian\",\n \"ru\": \"Russian\",\n \"sm\": \"Samoan\",\n \"gd\": \"Scots Gaelic\",\n \"sr\": \"Serbian\",\n \"st\": \"Sesotho\",\n \"sn\": \"Shona\",\n \"sd\": \"Sindhi\",\n \"si\": \"Sinhala (Sinhalese)\",\n \"sk\": \"Slovak\",\n \"sl\": \"Slovenian\",\n \"so\": \"Somali\",\n \"es\": \"Spanish\",\n \"su\": \"Sundanese\",\n \"sw\": \"Swahili\",\n \"sv\": \"Swedish\",\n \"tl\": \"Tagalog (Filipino)\",\n \"tg\": \"Tajik\",\n \"ta\": \"Tamil\",\n \"te\": \"Telugu\",\n \"th\": \"Thai\",\n \"tr\": \"Turkish\",\n \"uk\": \"Ukrainian\",\n \"ur\": \"Urdu\",\n \"uz\": \"Uzbek\",\n \"vi\": \"Vietnamese\",\n \"cy\": \"Welsh\",\n \"xh\": \"Xhosa\",\n \"yi\": \"Yiddish\",\n \"yo\": \"Yoruba\",\n \"zu\": \"Zulu\"\n}","import langs from '@core/constants/all-langs.json'\n\nexport const getRespondCardTool = ({\n language,\n standard = 'actfl',\n}: {\n language: string\n standard: string\n}) => {\n const lang = langs[language as keyof typeof langs] || 'English'\n const tool = {\n tool_choice: {\n type: 'function',\n function: { name: 'get_feedback' },\n },\n tools: [\n {\n type: 'function',\n function: {\n name: 'get_feedback',\n description: \"Get feedback on a student's response\",\n parameters: {\n type: 'object',\n required: [\n 'success',\n 'score',\n 'score_justification',\n 'errors',\n 'improvedResponse',\n 'compliments',\n ],\n properties: {\n success: {\n type: 'boolean',\n description:\n \"Mark true if the student's response was on-topic and generally demonstrated understanding. A few grammar mistakes are acceptable. Mark false if the student's response was off-topic or did not demonstrate understanding.\",\n },\n\n errors: {\n type: 'array',\n items: {\n type: 'object',\n required: ['error', 'grammar_error_type', 'correction', 'justification'],\n properties: {\n error: {\n type: 'string',\n description: \"The grammatical error in the student's response.\",\n },\n correction: {\n type: 'string',\n description: 'The suggested correction to the error',\n },\n justification: {\n type: 'string',\n description: `An explanation of the rationale behind the suggested correction. WRITE THIS IN ${lang}!`,\n },\n grammar_error_type: {\n type: 'string',\n enum: [\n 'subjVerbAgree',\n 'tenseErrors',\n 'articleMisuse',\n 'prepositionErrors',\n 'adjNounAgree',\n 'pronounErrors',\n 'wordOrder',\n 'verbConjugation',\n 'pluralization',\n 'negationErrors',\n 'modalVerbMisuse',\n 'relativeClause',\n 'auxiliaryVerb',\n 'complexSentenceAgreement',\n 'idiomaticExpression',\n 'registerInconsistency',\n 'voiceMisuse',\n ],\n description:\n 'The type of grammatical error found. It should be one of the following categories: subject-verb agreement, tense errors, article misuse, preposition errors, adjective-noun agreement, pronoun errors, word order, verb conjugation, pluralization errors, negation errors, modal verb misuse, relative clause errors, auxiliary verb misuse, complex sentence agreement, idiomatic expression, register inconsistency, or voice misuse',\n },\n },\n },\n description:\n \"An array of objects, each representing a grammatical error in the student's response. Each object should have the following properties: error, grammar_error_type, correction, and justification. If there were no errors, return an empty array.\",\n },\n compliments: {\n type: 'array',\n items: {\n type: 'string',\n },\n description: `An array of strings, each representing something the student did well. Each string should be WRITTEN IN ${lang}!`,\n },\n improvedResponse: {\n type: 'string',\n description:\n 'An improved response with proper grammar and more detail, if applicable.',\n },\n score: {\n type: 'number',\n description:\n 'A score between 0 and 100, reflecting the overall quality of the response',\n },\n score_justification: {\n type: 'string',\n description:\n 'An explanation of the rationale behind the assigned score, considering both accuracy and fluency',\n },\n },\n },\n },\n },\n ],\n }\n\n if (standard === 'wida') {\n // add wida level\n const wida_level = {\n type: 'number',\n enum: [1, 2, 3, 4, 5, 6],\n description: `The student's WIDA (World-Class Instructional Design and Assessment) proficiency level. Choose one of the following options: 1, 2, 3, 4, 5, 6 which corresponds to\n\t\t\t\t\n\t\t\t\t1 - Entering\n\t\t\t\t2 - Emerging\n\t\t\t\t3 - Developing\n\t\t\t\t4 - Expanding\n\t\t\t\t5 - Bridging\n\t\t\t\t6 - Reaching\n\t\t\t\t\n\t\t\tThis is an estimate based on the level of the student's response. Use the descriptions of the WIDA speaking standards to guide your decision.\n\t\t\t\t`,\n }\n const wida_justification = {\n type: 'string',\n description: `An explanation of the rationale behind the assigned WIDA level of the response, considering both accuracy and fluency. WRITE THIS IN ENGLISH!`,\n }\n\n tool.tools[0].function.parameters.required.push('wida_level')\n tool.tools[0].function.parameters.required.push('wida_justification')\n // @ts-ignore\n tool.tools[0].function.parameters.properties.wida_level = wida_level\n // @ts-ignore\n tool.tools[0].function.parameters.properties.wida_justification = wida_justification\n } else {\n const actfl_level = {\n type: 'string',\n enum: ['NL', 'NM', 'NH', 'IL', 'IM', 'IH', 'AL', 'AM', 'AH', 'S', 'D'],\n description:\n \"The student's ACTFL (American Council on the Teaching of Foreign Languages) proficiency level. Choose one of the following options: NL, NM, NH, IL, IM, IH, AL, AM, AH, S, or D\",\n }\n\n const actfl_justification = {\n type: 'string',\n description:\n 'An explanation of the rationale behind the assigned ACTFL level, considering both accuracy and fluency',\n }\n\n tool.tools[0].function.parameters.required.push('actfl_level')\n tool.tools[0].function.parameters.required.push('actfl_justification')\n // @ts-ignore\n tool.tools[0].function.parameters.properties.actfl_level = actfl_level\n // @ts-ignore\n tool.tools[0].function.parameters.properties.actfl_justification = actfl_justification\n }\n\n return tool\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport {\n type AssignmentWithId,\n ActivityPageType,\n type PageScore,\n type Score,\n type ScoreWithId,\n type SetWithId,\n useAssignment,\n useCards,\n useSet,\n} from '@core/domains'\nimport {\n scoreQueryKeys,\n useClearScore,\n useScore,\n useSubmitAssignmentScore,\n useSubmitPracticeScore,\n useUpdateCardScore,\n useUpdateScore,\n} from '@core/domains/assignment/hooks/score-hooks'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { useEffect } from 'react'\nimport { addGradingStandardLog } from '@core/services'\nimport { api } from '@core/lib/firebase/api'\nimport { logOpenActivityPreview, logOpenAssignment } from '@core/lib/firebase/firebase-analytics'\n\nimport { useActivityTracker } from './useActivityTracker'\n\nexport function useActivity({\n id,\n isAssignment,\n onAssignmentSubmitted,\n ltiData,\n}: {\n id: string\n isAssignment: boolean\n onAssignmentSubmitted: (assignmentId: string) => void\n ltiData?: {\n lineItemId?: string\n lti_id?: string\n serviceKey?: string\n }\n}) {\n const { queryClient, user } = useSpeakableApi()\n\n const userId = user.auth.uid\n\n const assignmentQuery = useAssignment({\n assignmentId: id,\n userId: userId,\n enabled: isAssignment,\n })\n\n const activeAssignment = assignmentQuery.data\n\n const setId = isAssignment ? (activeAssignment?.setId ?? '') : id\n\n const querySet = useSet({ setId: setId })\n\n const setData = querySet.data\n\n const assignmentContent = activeAssignment?.content\n const assignmentWeights = activeAssignment?.weights\n\n const setContent = setData?.content\n const setWeights = setData?.weights\n\n const contentCardsToUse = isAssignment ? (assignmentContent ?? setContent) : setContent\n const weightsToUse = isAssignment ? (assignmentWeights ?? setWeights) : setWeights\n\n const activityId = isAssignment ? (activeAssignment?.id ?? '') : setId\n\n const { cardsObject, cardsQueries, cards } = useCards({\n cardIds: contentCardsToUse ?? [],\n enabled: querySet.isSuccess,\n asObject: true,\n })\n\n // Filter out MEDIA_PAGE cards for score updates\n const scorableCardIds = (contentCardsToUse ?? []).filter(cardId => {\n const card = cardsObject?.[cardId]\n\n return card?.type !== ActivityPageType.MEDIA_PAGE\n })\n\n const scoreQuery = useScore({\n isAssignment,\n activityId: id,\n userId,\n courseId: activeAssignment?.courseId,\n googleClassroomUserId: user.profile.googleClassroomUserId,\n enabled: isAssignment ? assignmentQuery.isSuccess : querySet.isSuccess,\n })\n\n const { mutationUpdateScore } = useUpdateScore()\n const { mutationUpdateCardScore } = useUpdateCardScore({\n activityId: activityId,\n isAssignment,\n userId,\n cardIds: scorableCardIds,\n weights: weightsToUse ?? {},\n })\n\n const { mutationClearScore } = useClearScore()\n\n const { submitAssignmentScore } = useSubmitAssignmentScore({\n onAssignmentSubmitted: onAssignmentSubmitted,\n studentName: user.profile.displayName,\n })\n\n const { submitPracticeScore } = useSubmitPracticeScore()\n\n const handleUpdateScore = (data: Partial<Score>) => {\n mutationUpdateScore.mutate({\n data,\n isAssignment,\n activityId: activityId,\n userId,\n })\n }\n\n const handleUpdateCardScore = (cardId: string, cardScore: PageScore) => {\n mutationUpdateCardScore.mutate({ cardId, cardScore })\n\n if (cardScore.proficiency_level) {\n logGradingStandardEntry({\n type: cardScore.proficiency_level.standardId as 'actfl' | 'wida' | 'custom',\n cardId: cardId,\n gradingStandard: cardScore.proficiency_level,\n })\n } else if (cardScore.wida || cardScore.actfl) {\n logGradingStandardEntry({\n type: cardScore.wida ? 'wida' : 'actfl',\n cardId: cardId,\n gradingStandard: cardScore.wida || cardScore.actfl || { level: '', justification: '' },\n })\n }\n }\n\n const onClearScore = ({\n cardId,\n wasCompleted = true,\n }: {\n cardId: string\n wasCompleted?: boolean\n }) => {\n const currentCard = cardsObject?.[cardId]\n\n if (\n currentCard?.type === ActivityPageType.MULTIPLE_CHOICE ||\n currentCard?.type === ActivityPageType.READ_REPEAT\n ) {\n return\n }\n const queryKeys = scoreQueryKeys.byId(activityId)\n const activeCardScores = queryClient.getQueryData<Score>(queryKeys)?.cards?.[cardId]\n\n if (activeCardScores === undefined) return\n\n mutationClearScore.mutate({\n isAssignment,\n activityId: activityId,\n cardScores: activeCardScores,\n cardId,\n userId,\n })\n }\n\n const onSubmitScore = async () => {\n try {\n let results\n\n if (isAssignment) {\n // check card scores if any cards have a \"pending_review\" status\n // past the status to the submitAssignmentScore function\n\n const someCardIsManualGraded = cards.some(page => page.grading_method === 'manual')\n\n results = await submitAssignmentScore({\n assignment: {\n id: assignmentQuery.data?.id ?? '',\n name: assignmentQuery.data?.name ?? '',\n owners: assignmentQuery.data?.owners ?? [],\n courseId: assignmentQuery.data?.courseId ?? '',\n courseWorkId: assignmentQuery.data?.courseWorkId ?? '',\n isAssessment: assignmentQuery.data?.isAssessment ?? false,\n maxPoints: assignmentQuery.data?.maxPoints ?? 0,\n },\n userId: userId,\n cardIds: scorableCardIds,\n scores: scoreQuery.data as Score,\n weights: weightsToUse ?? {},\n status: someCardIsManualGraded ? 'PENDING_REVIEW' : 'SUBMITTED',\n })\n if (assignmentQuery.data?.ltiDeeplink) {\n submitLTIScore({\n maxPoints: assignmentQuery.data?.maxPoints,\n score: scoreQuery.data?.score ?? 0,\n SERVICE_KEY: ltiData?.serviceKey ?? '',\n lineItemId: ltiData?.lineItemId ?? '',\n lti_id: ltiData?.lti_id ?? '',\n })\n }\n\n // if (activeAssignment?.checkpointId) {\n // const submitCheckpointAssignment = httpsCallable(functions, 'submitCheckpointAssignment')\n\n // const results = await submitCheckpointAssignment({\n // checkpointId: activeAssignment.checkpointId,\n // assignmentId: activeAssignment.id,\n // studentId: auth.uid,\n // classroomId: activeAssignment.courseId,\n // teacherId: activeAssignment.owners[0],\n // })\n // console.log('checkpoint assignment results', results)\n // }\n } else {\n results = await submitPracticeScore({\n setId: querySet.data?.id ?? '',\n userId: userId,\n scores: scoreQuery.data!,\n })\n }\n\n return results\n } catch (error) {\n return {\n success: false,\n error: error,\n }\n }\n }\n\n const logGradingStandardEntry = ({\n cardId,\n gradingStandard,\n type,\n }: {\n cardId: string\n gradingStandard: {\n level: string\n justification: string\n }\n type: 'actfl' | 'wida' | 'custom'\n }) => {\n const card = cardsObject?.[cardId]\n const scoresObject = queryClient.getQueryData<ScoreWithId>(scoreQueryKeys.byId(activityId))\n const cardScore = scoresObject?.cards?.[cardId]\n\n const serverTimestamp = api.helpers.serverTimestamp\n\n addGradingStandardLog(\n {\n assignmentId: activeAssignment?.id ?? '',\n courseId: activeAssignment?.courseId ?? '',\n teacherId: activeAssignment?.owners[0] ?? '',\n setId: setData?.id ?? '',\n cardId: cardId,\n level: gradingStandard.level,\n justification: gradingStandard.justification,\n transcript: cardScore?.transcript ?? '',\n audioUrl: cardScore?.audio ?? '',\n prompt: card?.prompt ?? '',\n responseType: card?.type === ActivityPageType.RESPOND_WRITE ? 'written' : 'spoken',\n type: type,\n dateMade: serverTimestamp(),\n language: card?.language ?? '',\n },\n userId,\n )\n }\n\n useEffect(() => {\n if (isAssignment) {\n logOpenAssignment({ assignmentId: id })\n } else {\n logOpenActivityPreview({ setId: id })\n }\n }, [])\n\n useInitActivity({\n assignment: activeAssignment ?? undefined,\n set: setData ?? undefined,\n enabled: !!setData,\n userId,\n })\n\n return {\n set: {\n data: setData,\n query: querySet,\n },\n cards: {\n data: cardsObject,\n query: cardsQueries,\n cardsArray: cards,\n },\n assignment: {\n data: isAssignment ? activeAssignment : undefined,\n query: assignmentQuery,\n },\n scores: {\n data: scoreQuery.data,\n query: scoreQuery,\n actions: {\n update: handleUpdateScore,\n clear: onClearScore,\n submit: onSubmitScore,\n updateCard: handleUpdateCardScore,\n logGradingStandardEntry: logGradingStandardEntry,\n },\n },\n }\n}\n\nconst useInitActivity = ({\n assignment,\n set,\n enabled,\n userId,\n}: {\n assignment?: AssignmentWithId\n set?: SetWithId\n enabled: boolean\n userId: string\n}) => {\n const { trackActivity } = useActivityTracker({ userId: userId })\n\n const init = () => {\n if (!enabled) return\n if (!assignment) {\n trackActivity({\n activityName: set?.name ?? '',\n activityType: 'set',\n id: set?.id,\n language: set?.language,\n })\n } else if (assignment.name) {\n // localStorage.setItem('speakable_course_id', assignment.courseId)\n trackActivity({\n activityName: assignment.name,\n activityType: assignment.isAssessment ? 'assessment' : 'assignment',\n id: assignment.id,\n language: set?.language,\n })\n }\n if (set?.public) {\n api.httpsCallable?.('onSetOpened')?.({\n setId: set.id,\n language: set.language,\n })\n }\n\n api.httpsCallable?.('updateAlgoliaIndex')?.({\n updatePlays: true,\n objectID: set?.id,\n })\n }\n\n useEffect(() => {\n init()\n }, [set])\n}\n\nconst submitLTIScore = async ({\n maxPoints,\n score,\n SERVICE_KEY,\n lineItemId,\n lti_id,\n}: {\n maxPoints: number\n score: number\n SERVICE_KEY: string\n lineItemId: string\n lti_id: string\n}) => {\n try {\n if (!SERVICE_KEY || !lineItemId || !lti_id) {\n throw new Error('Missing required LTI credentials')\n }\n\n const earnedPoints = score ? (score / 100) * maxPoints : 0\n const { data } = await api.httpsCallable?.('submitLTIAssignmentScore')?.({\n SERVICE_KEY,\n scoreData: {\n lineItemId,\n userId: lti_id,\n maxPoints,\n earnedPoints,\n },\n })\n\n return { success: true, data }\n } catch (error) {\n console.error('Failed to submit LTI score:', error)\n\n return {\n success: false,\n error: error instanceof Error ? error : new Error('Unknown error occurred'),\n }\n }\n}\n","import { api } from '@core/lib/firebase/api'\nimport { logGradingStandardLog } from '@core/lib/firebase/firebase-analytics'\nimport { type FieldValue } from 'firebase/firestore'\n\nexport interface GradingStandard {\n type: 'actfl' | 'wida' | 'custom'\n customStandardId?: string | undefined\n dateMade: FieldValue\n courseId?: string\n assignmentId?: string\n teacherId?: string\n cardId: string\n setId: string\n level: string\n justification: string\n prompt: string\n transcript: string\n audioUrl?: string\n responseType: 'spoken' | 'written'\n language: string\n}\n\nexport const addGradingStandardLog = async (gradingStandard: GradingStandard, userId: string) => {\n logGradingStandardLog(gradingStandard)\n const path = `users/${userId}/grading_standard_logs`\n\n await api.addDoc(path, gradingStandard)\n}\n","import { api } from '@core/lib/firebase/api'\nimport { v4 } from 'uuid'\n\nexport function useActivityTracker({ userId }: { userId: string }) {\n const trackActivity = async ({\n activityName,\n activityType,\n id = v4(),\n language = '',\n }: {\n activityName: string\n activityType: 'assignment' | 'assessment' | 'set'\n id?: string\n language?: string\n }) => {\n if (userId) {\n const { doc, serverTimestamp, setDoc } = api.accessHelpers()\n\n const activityRef = doc(`users/${userId}/activity/${id}`)\n\n const timestamp = serverTimestamp()\n\n await setDoc(activityRef, {\n name: activityName,\n type: activityType,\n lastSeen: timestamp,\n id,\n language,\n })\n }\n }\n\n return {\n trackActivity,\n }\n}\n","import { api } from '@core/lib/firebase/api'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { useQuery } from '@tanstack/react-query'\n\nexport interface CreditContract {\n allocationSource: string\n createdAt: string\n creditsAllocatedThisPeriod: number\n effectivePlanId: string\n email: string\n isUnlimited: boolean\n lastUpdatedAt: string // Formato de fecha ISO o timestamp\n ownerType: string\n periodStart: string // Formato de fecha ISO o timestamp\n periodEnd: string // Formato de fecha ISO o timestamp\n planTermEndTimestamp: string | null\n sourceDetails: Record<string, unknown>\n creditsAvailable?: number\n topOffCreditsAvailable?: number\n}\n\nexport const creditQueryKeys = {\n userCredits: (uid: string) => ['userCredits', uid] as const,\n}\n\nexport const useUserCredits = () => {\n const { user } = useSpeakableApi()\n\n const email = user.auth.email\n const uid = user.auth.uid\n\n const query = useQuery({\n queryKey: creditQueryKeys.userCredits(uid),\n queryFn: () => fetchUserCredits({ uid, email }),\n enabled: !!uid,\n refetchInterval: 1000 * 60 * 5,\n })\n\n return {\n ...query,\n }\n}\n\nconst fetchUserCredits = async ({ uid, email }: { uid: string; email: string }) => {\n if (!uid) {\n throw new Error('User ID is required')\n }\n\n const contractSnap = await api.getDoc<CreditContract>(`creditContracts/${uid}`)\n\n if (contractSnap.data == null) {\n return {\n id: uid,\n userId: uid,\n email: email,\n effectivePlanId: 'free_tier',\n status: 'inactive',\n isUnlimited: false,\n creditsAvailable: 100,\n creditsAllocatedThisPeriod: 100,\n topOffCreditsAvailable: 0,\n topOffCreditsTotal: 0,\n allocationSource: 'free_tier',\n sourceDetails: {},\n periodStart: null,\n periodEnd: null,\n planTermEndTimestamp: null,\n ownerType: 'individual',\n createdAt: new Date().toISOString(),\n lastUpdatedAt: new Date().toISOString(),\n }\n }\n\n const contractData = contractSnap.data\n\n // Calculate total available credits using existing fields\n //@ts-ignore\n const monthlyCredits = contractData?.creditsAvailable || 0\n //@ts-ignore\n const topOffCredits = contractData?.topOffCreditsAvailable || 0\n const totalCredits = monthlyCredits + topOffCredits\n\n return {\n id: contractSnap.id,\n ...contractData,\n // Add computed total for convenience\n totalCreditsAvailable: totalCredits,\n }\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { api } from '@core/lib/firebase/api'\n\nexport interface OrganizationAccess {\n hasUnlimitedAccess: boolean\n subscriptionId: string | null\n organizationId: string | null\n organizationName: string | null\n subscriptionEndDate: Date | null\n accessType: 'organization' | 'individual' | 'institution_subscriptions'\n}\n\nexport interface InstitutionSubscription {\n id: string\n institutionId: string\n name: string\n plan: string\n endDate: Date\n}\n\nexport interface Organization {\n id: string\n name: string\n members: string[]\n masterSubscriptionStatus: string\n masterSubscriptionId: string\n masterSubscriptionEndDate: Date\n}\n\nexport const useOrganizationAccess = () => {\n const { user } = useSpeakableApi()\n\n const email = user.auth.email\n\n const query = useQuery({\n queryKey: ['organizationAccess', email],\n queryFn: async (): Promise<OrganizationAccess> => {\n if (!email) {\n return {\n hasUnlimitedAccess: false,\n subscriptionId: null,\n organizationId: null,\n organizationName: null,\n subscriptionEndDate: null,\n accessType: 'individual',\n }\n }\n\n return getOrganizationAccess(email)\n },\n enabled: !!email, // Only run query if we have a user email\n staleTime: 5 * 60 * 1000, // Consider data fresh for 5 minutes\n gcTime: 10 * 60 * 1000, // Keep in cache for 10 minutes\n retry: 2, // Retry failed requests twice\n })\n\n return {\n ...query,\n }\n}\n\nconst getOrganizationAccess = async (email: string): Promise<OrganizationAccess> => {\n const { limit, where } = api.accessQueryConstraints()\n\n try {\n const organizationSnapshot = await api.getDocs<Organization>(\n 'organizations',\n where('members', 'array-contains', email),\n where('masterSubscriptionStatus', '==', 'active'),\n limit(1),\n )\n\n if (!organizationSnapshot.empty) {\n // User is a member of an organization with active subscription\n const orgData = organizationSnapshot.data[0]\n\n return {\n hasUnlimitedAccess: true,\n subscriptionId: orgData?.masterSubscriptionId,\n organizationId: orgData.id,\n organizationName: orgData.name || 'Unknown Organization',\n subscriptionEndDate: orgData.masterSubscriptionEndDate || null,\n accessType: 'organization',\n }\n }\n\n // Check legacy institution subscriptions\n\n const institutionSnapshot = await api.getDocs<InstitutionSubscription>(\n 'institution_subscriptions',\n where('users', 'array-contains', email),\n where('active', '==', true),\n limit(1),\n )\n\n if (!institutionSnapshot.empty) {\n // User has legacy institution subscription\n const institutionData = institutionSnapshot.data[0]\n const isUnlimited =\n institutionData?.plan === 'organization' || institutionData?.plan === 'school_starter'\n\n return {\n hasUnlimitedAccess: isUnlimited,\n subscriptionId: institutionData.id,\n organizationId: institutionData?.institutionId,\n organizationName:\n institutionData.name || institutionData.institutionId || 'Legacy Institution',\n subscriptionEndDate: institutionData.endDate || null,\n accessType: 'institution_subscriptions',\n }\n }\n\n // No organization or legacy subscription access found\n return {\n hasUnlimitedAccess: false,\n subscriptionId: null,\n organizationId: null,\n organizationName: null,\n subscriptionEndDate: null,\n accessType: 'individual',\n }\n } catch (error) {\n console.error('Error checking organization access:', error)\n\n // Return individual access on error to be safe\n return {\n hasUnlimitedAccess: false,\n subscriptionId: null,\n organizationId: null,\n organizationName: null,\n subscriptionEndDate: null,\n accessType: 'individual',\n }\n }\n}\n","import { getTranscript, getTranscriptCycle } from '@core/utils'\nimport { useMutation } from '@tanstack/react-query'\n\nexport function useSpeakableTranscript() {\n const mutation = useMutation({\n mutationFn: async ({\n model,\n audioUrl,\n language,\n prompt,\n }: {\n model: 'gemini' | 'assemblyai' | 'whisper'\n audioUrl: string\n language: string\n prompt?: string\n }) => {\n return getTranscript(model, { audioUrl, language, prompt })\n },\n retry: false,\n })\n\n return {\n mutation,\n }\n}\n\nexport function useSpeakableTranscriptCycle() {\n const mutation = useMutation({\n mutationFn: async (args: { audioUrl: string; language: string; prompt: string }) => {\n return getTranscriptCycle(args)\n },\n retry: false,\n })\n\n return {\n mutationTranscriptCycle: mutation,\n }\n}\n","import { type PageActivityWithId } from '@core/domains'\nimport { api } from '@core/lib/firebase/api'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { cleanString, getPhraseLength, getWordHash } from '@core/utils'\n\nexport const useUpdateStudentVocab = (page: PageActivityWithId | null) => {\n const { user } = useSpeakableApi()\n\n const currentUserId = user?.auth.uid\n\n if (!page || !currentUserId || !page.target_text || !page.language) {\n return {\n studentVocabMarkVoiceSuccess: undefined,\n studentVocabMarkVoiceFail: undefined,\n }\n }\n\n const getDataObject = () => {\n const { serverTimestamp } = api.accessHelpers()\n\n const language = page.language ?? 'en'\n const word = page.target_text ?? ''\n const phrase_length = getPhraseLength(word)\n const wordHash = getWordHash(word, language)\n const docPath = `users/${currentUserId}/vocab/${wordHash}`\n const communityPath = `checked-pronunciations/${wordHash}`\n\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n const id = `${language}-${cleanString(word)}`\n const data = {\n id: id,\n word: word,\n words: word?.split(' ') || [],\n wordHash: wordHash,\n language: language,\n lastSeen: serverTimestamp(),\n phrase_length: phrase_length,\n }\n\n return {\n docPath,\n communityPath,\n data,\n }\n }\n\n const markVoiceSuccess = async () => {\n const { docPath, communityPath, data } = getDataObject()\n const { increment } = api.accessQueryConstraints()\n const { serverTimestamp } = api.accessHelpers()\n\n // @ts-ignore\n data.voiceSuccess = increment(1)\n try {\n await api.updateDoc(docPath, data)\n } catch (error) {\n if (error instanceof Error && error.message === 'not-found') {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n data.firstSeen = serverTimestamp()\n await api.setDoc(docPath, data, { merge: true })\n } else {\n console.log(error)\n }\n }\n\n try {\n // @ts-ignore\n data.pronunciations = increment(1)\n await api.setDoc(communityPath, data, { merge: true })\n } catch (error) {\n console.log(error)\n }\n }\n\n const markVoiceFail = async () => {\n const { docPath, communityPath, data } = getDataObject()\n const { increment } = api.accessQueryConstraints()\n const { serverTimestamp } = api.accessHelpers()\n\n // @ts-ignore\n data.voiceFail = increment(1)\n try {\n await api.updateDoc(docPath, data)\n } catch (error) {\n if (error instanceof Error && error.message === 'not-found') {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n data.firstSeen = serverTimestamp()\n await api.setDoc(docPath, data, { merge: true })\n } else {\n console.log(error)\n }\n }\n\n try {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n data.fails = increment(1)\n await api.setDoc(communityPath, data, { merge: true })\n } catch (error) {\n console.log(error)\n }\n }\n\n return {\n studentVocabMarkVoiceSuccess: markVoiceSuccess,\n studentVocabMarkVoiceFail: markVoiceFail,\n }\n}\n","import { api } from '@core/lib/firebase/api'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { useQuery } from '@tanstack/react-query'\n\nexport interface StudentTeacherPlanResult {\n studentId: string\n teachers: {\n teacherId: string\n teacherName: string\n teacherEmail: string\n plan: string\n hasActiveTeamPlan: boolean\n hasActiveOrgPlan: boolean\n hasUnlimitedAccess: boolean\n }[]\n hasTeacherWithTeamPlan: boolean\n hasTeacherWithOrgPlan: boolean\n hasTeacherWithUnlimitedAccess: boolean\n canAccessFeedback: boolean\n reason?: string\n}\n\nexport interface ActivityFeedbackAccess {\n canAccessFeedback: boolean\n reason?: string\n isUnlimited: boolean\n accessType: 'ai_enabled' | 'teacher_preview' | 'student_with_teacher_plan' | 'none'\n}\n\nexport const activityFeedbackAccessQueryKeys = {\n activityFeedbackAccess: (args: { aiEnabled: boolean; isActivityRoute: boolean }) =>\n ['activityFeedbackAccess', ...Object.values(args)] as const,\n}\n\n/**\n * Hook to check feedback permissions for both students and teachers\n *\n * Permission Logic:\n * 1. aiEnabled: true → Allow feedback access always (highest priority)\n * 2. Teachers on /activity route → Always allowed (ADMIN role)\n * 3. Students on /activity route → Need teacher with active plan (team/org)\n *\n * @param params - Parameters for permission checking\n * @returns Feedback permissions information\n */\n\nexport const useActivityFeedbackAccess = ({\n aiEnabled = false,\n isActivityRoute = false,\n}: {\n aiEnabled?: boolean\n isActivityRoute?: boolean\n}) => {\n const { user } = useSpeakableApi()\n\n const uid = user.auth.uid\n const isTeacher = user.profile?.isTeacher\n const isStudent = user.profile?.isStudent\n const userRoles = user.profile?.roles || []\n\n const query = useQuery({\n queryKey: activityFeedbackAccessQueryKeys.activityFeedbackAccess({\n aiEnabled,\n isActivityRoute,\n }),\n queryFn: async (): Promise<ActivityFeedbackAccess> => {\n if (!uid) {\n return {\n canAccessFeedback: false,\n reason: 'Missing user ID',\n isUnlimited: false,\n accessType: 'none',\n }\n }\n\n try {\n // Priority 1: aiEnabled override (highest priority)\n if (aiEnabled) {\n return {\n canAccessFeedback: true,\n reason: 'AI feedback enabled',\n isUnlimited: true,\n accessType: 'ai_enabled',\n }\n }\n\n // Priority 2: Teachers (preview access) - any teacher can test their creations\n if (isTeacher || userRoles.includes('ADMIN')) {\n return {\n canAccessFeedback: true,\n reason: 'Teacher preview access',\n isUnlimited: true,\n accessType: 'teacher_preview',\n }\n }\n\n // Priority 3: Students on /activity route (need teacher with active plan)\n if (isStudent && isActivityRoute) {\n try {\n // Call the cloud function to check student teacher plans\n\n const result = (await api.httpsCallable?.('checkStudentTeacherPlan')?.({\n studentId: uid,\n })) as {\n data: StudentTeacherPlanResult\n }\n\n const planCheckResult = result.data\n\n if (planCheckResult.canAccessFeedback) {\n return {\n canAccessFeedback: true,\n reason: planCheckResult.reason || 'Student access via teacher with active plan',\n isUnlimited: planCheckResult.hasTeacherWithUnlimitedAccess,\n accessType: 'student_with_teacher_plan',\n }\n } else {\n return {\n canAccessFeedback: false,\n reason: planCheckResult.reason || 'No teacher with active plan found',\n isUnlimited: false,\n accessType: 'none',\n }\n }\n } catch (error: unknown) {\n console.error('Error checking student teacher plan:', error)\n\n return {\n canAccessFeedback: false,\n reason: 'Error checking teacher plans',\n isUnlimited: false,\n accessType: 'none',\n }\n }\n }\n\n // Default: no access\n return {\n canAccessFeedback: false,\n reason: 'No access permissions found for current context',\n isUnlimited: false,\n accessType: 'none',\n }\n } catch (error: unknown) {\n console.error('Error checking activity feedback access:', error)\n\n return {\n canAccessFeedback: false,\n reason: 'Error checking access permissions',\n isUnlimited: false,\n accessType: 'none',\n }\n }\n },\n enabled: !!uid,\n staleTime: 5 * 60 * 1000, // 5 minutes\n gcTime: 10 * 60 * 1000, // 10 minutes\n })\n\n return {\n ...query,\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { getCardFromCache } from '@core/domains'\nimport { getRespondCardTool } from '@core/utils/ai/get-respond-card-tool'\nimport { api } from '@core/lib/firebase/api'\n\nimport { useActivityFeedbackAccess } from './useActivityFeedbackAccess'\n\nexport const useBaseOpenAI = ({\n onTranscriptSuccess,\n onTranscriptError,\n onCompletionSuccess,\n onCompletionError,\n aiEnabled,\n submitAudioResponse,\n uploadAudioAndGetTranscript,\n onGetAudioUrlAndTranscript,\n}: {\n onTranscriptSuccess: (transcript: string) => void\n onTranscriptError: ({ type, message }: { type: string; message: string }) => void\n onCompletionSuccess: (completion: any) => void\n onCompletionError: ({ type, message }: { type: string; message: string }) => void\n aiEnabled: boolean\n submitAudioResponse: (audio: string) => Promise<{ url: string; fileName: string }>\n uploadAudioAndGetTranscript: (\n audio: string,\n language: string,\n pagePrompt: string | null,\n ) => Promise<{\n transcript: string\n audioUrl: string\n }>\n onGetAudioUrlAndTranscript?: (args: { transcript?: string; audioUrl?: string }) => void\n}) => {\n const { user, queryClient } = useSpeakableApi()\n\n const currentUserId = user.auth.uid\n\n const { data: feedbackAccess } = useActivityFeedbackAccess({\n aiEnabled,\n })\n\n const getTranscript = async (audioUrl: string, language: string, prompt?: string) => {\n const getGeminiTranscript = api.httpsCallable?.('getGeminiTranscript')\n const getAssemblyAITranscript = api.httpsCallable?.('transcribeAssemblyAIAudio')\n const getWhisperTranscript = api.httpsCallable?.('transcribeAudio')\n\n try {\n const { data } = await getWhisperTranscript?.({\n audioUrl,\n language: language,\n })\n\n const transcript = data\n\n if (transcript) {\n return transcript\n }\n } catch (error) {\n console.log('Whisper transcript failed, trying Gemini fallback:', error)\n }\n\n try {\n const { data } = await getGeminiTranscript?.({\n audioUrl,\n targetLanguage: language,\n prompt: prompt || '',\n })\n\n const transcript = data.transcript\n\n if (transcript) {\n return transcript\n }\n } catch (error) {\n console.log('Gemini transcript failed, trying AssemblyAI fallback:', error)\n }\n\n try {\n const response = await getAssemblyAITranscript?.({\n audioUrl: audioUrl,\n language: language,\n })\n\n const transcript = response?.data as string\n\n if (transcript) {\n return transcript\n }\n\n throw new Error('Both transcript services failed')\n } catch (error) {\n console.log('AssemblyAI transcript also failed:', error)\n onTranscriptError({\n type: 'TRANSCRIPT',\n message: (error as Error)?.message || 'Error getting transcript from both services',\n })\n\n throw new Error(error as string)\n }\n }\n\n const getFreeResponseCompletion = async (\n messages: string[],\n isFreeResponse: boolean,\n feedbackLanguage: string,\n gradingStandard = 'actfl',\n ) => {\n const responseTool = getRespondCardTool({\n language: feedbackLanguage,\n standard: gradingStandard,\n })\n\n try {\n const createChatCompletion = api.httpsCallable?.('createChatCompletion')\n\n const {\n data: {\n response,\n prompt_tokens = 0,\n completion_tokens = 0,\n success: aiSuccess = false, // the AI was able to generate a response\n },\n } = (await createChatCompletion?.({\n chat: {\n model: isFreeResponse ? 'gpt-4-1106-preview' : 'gpt-3.5-turbo-1106',\n messages: messages,\n temperature: 0.7,\n ...responseTool,\n },\n type: isFreeResponse ? 'LONG_RESPONSE' : 'SHORT_RESPONSE',\n })) as {\n data: {\n response: any\n prompt_tokens: number\n completion_tokens: number\n success: boolean\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n const functionArguments = JSON.parse(response?.tool_calls?.[0]?.function?.arguments || '{}')\n\n const result = {\n ...functionArguments,\n prompt_tokens,\n completion_tokens,\n aiSuccess,\n }\n\n onCompletionSuccess(result)\n\n return result\n } catch (error) {\n onCompletionError({\n type: 'COMPLETION',\n message: (error as Error)?.message || 'Error getting completion',\n })\n throw new Error(error as string)\n }\n }\n\n const getFeedback = async ({\n cardId,\n language = 'en', // required\n writtenResponse = null, // if the type = RESPOND_WRITE\n audio = null,\n autoGrade = true,\n file = null,\n pagePrompt = null,\n }: {\n cardId: string\n language: string\n writtenResponse: string | null\n audio: string | null\n autoGrade: boolean\n file: string | null\n pagePrompt: string | null\n }) => {\n try {\n // NEW CODE - Check feedback access first\n if (!feedbackAccess?.canAccessFeedback) {\n const result = {\n noFeedbackAvailable: true,\n success: true,\n reason: feedbackAccess?.reason || 'No feedback access',\n accessType: feedbackAccess?.accessType || 'none',\n }\n\n onCompletionSuccess(result)\n\n return result\n }\n\n let transcript\n let audioUrl = undefined\n\n if (writtenResponse) {\n transcript = writtenResponse\n onTranscriptSuccess(writtenResponse)\n } else if (typeof audio === 'string' && file) {\n // NEW CODE - Use feedbackAccess for transcript permission\n if (feedbackAccess?.canAccessFeedback) {\n transcript = await getTranscript(audio, language, pagePrompt ?? '')\n audioUrl = audio\n onTranscriptSuccess(transcript)\n } else {\n console.info(\n `Transcript not available: ${feedbackAccess?.reason || 'No feedback access'}`,\n )\n }\n } else {\n const response = await uploadAudioAndGetTranscript(audio || '', language, pagePrompt ?? '')\n\n transcript = response.transcript\n audioUrl = response.audioUrl\n }\n\n onGetAudioUrlAndTranscript?.({ transcript, audioUrl: audioUrl })\n\n // NEW CODE - Use feedbackAccess instead of plan-based checks\n if (feedbackAccess?.canAccessFeedback) {\n const results = await getAIResponse({\n cardId,\n transcript: transcript || '',\n })\n\n let output = results\n\n if (!autoGrade) {\n output = {\n ...output,\n noFeedbackAvailable: true,\n success: true,\n }\n }\n onCompletionSuccess(output)\n\n return output\n } else {\n const result = {\n noFeedbackAvailable: true,\n success: true,\n reason: feedbackAccess?.reason || 'No feedback access',\n accessType: feedbackAccess?.accessType || 'none',\n }\n\n onCompletionSuccess(result)\n\n return result\n }\n\n // OLD CODE - Commented out for comparison\n // if (AdvancedFeedbackPlans.includes(plan) || BasicFeedbackPlans.includes(plan)) {\n // const results = await getAIResponse({\n // cardId,\n // transcript,\n // autoGrade,\n // feedback_language,\n // })\n // let output = results\n\n // if (!autoGrade) {\n // output = {\n // ...output,\n // noFeedbackAvailable: true,\n // success: true,\n // }\n // }\n // onCompletionSuccess(output)\n\n // return output\n // } else {\n // onCompletionSuccess({\n // noFeedbackAvailable: true,\n // success: true,\n // })\n\n // return {\n // noFeedbackAvailable: true,\n // success: true,\n // }\n // }\n } catch (error) {\n console.error('Error getting feedback:', error)\n throw new Error(error as string)\n }\n }\n\n const getAIResponse = async ({ cardId, transcript }: { cardId: string; transcript: string }) => {\n try {\n const getGeminiFeedback = api.httpsCallable?.('callGetFeedback')\n const getProficiencyEstimate = api.httpsCallable?.('getProficiencyEstimate')\n\n const card = getCardFromCache({\n cardId,\n queryClient,\n })\n\n let feedbackData\n let proficiencyData = {}\n\n if (card && card.grading_method === 'manual') {\n } else if (card && card.grading_method !== 'standards_based') {\n const [geminiResult, proficiencyResult] = await Promise.all([\n getGeminiFeedback?.({\n cardId,\n studentId: currentUserId,\n studentResponse: transcript,\n }),\n getProficiencyEstimate?.({\n cardId,\n studentId: currentUserId,\n studentResponse: transcript,\n }),\n ])\n\n proficiencyData = proficiencyResult?.data || {}\n feedbackData = {\n ...(geminiResult?.data ?? {}),\n // @ts-ignore\n proficiency_level: proficiencyData?.proficiency_level || null,\n }\n } else {\n const geminiResult = await getGeminiFeedback?.({\n cardId,\n studentId: currentUserId,\n studentResponse: transcript,\n })\n\n feedbackData = geminiResult?.data\n }\n\n const results = {\n ...proficiencyData,\n ...feedbackData,\n aiSuccess: true,\n promptSuccess: feedbackData?.success || false,\n transcript,\n }\n\n return results as {\n noFeedbackAvailable: boolean\n success: boolean\n reason: string\n accessType: string\n aiSuccess: boolean\n }\n } catch (error) {\n onCompletionError({\n type: 'AI_FEEDBACK',\n message: (error as Error)?.message || 'Error getting ai feedback',\n })\n throw new Error(error as string)\n }\n }\n\n return {\n submitAudioResponse,\n uploadAudioAndGetTranscript,\n getTranscript,\n getFreeResponseCompletion,\n getFeedback,\n }\n}\n","import {\n getDoc,\n getDocs,\n addDoc,\n setDoc,\n updateDoc,\n deleteDoc,\n runTransaction,\n writeBatch,\n doc,\n collection,\n query,\n serverTimestamp,\n orderBy,\n limit,\n startAt,\n startAfter,\n endAt,\n endBefore,\n where,\n increment,\n} from '@react-native-firebase/firestore'\nimport { type FirestoreHelpers } from '@core/types/firebase.types'\n\nimport { createFsClientBase, type FsClientParams } from './create-firebase-client'\n\nexport const createFsClientNative = ({ db, httpsCallable, logEvent }: FsClientParams) => {\n return createFsClientBase({\n db,\n httpsCallable,\n logEvent,\n helpers: {\n getDoc,\n getDocs,\n addDoc,\n setDoc,\n updateDoc,\n deleteDoc,\n runTransaction,\n writeBatch,\n doc,\n collection,\n query,\n serverTimestamp,\n orderBy,\n limit,\n startAt,\n startAfter,\n endAt,\n endBefore,\n where,\n increment,\n } as unknown as FirestoreHelpers,\n })\n}\n","import { createAssignmentRepo, createCardRepo } from '@core/domains'\nimport {\n type FirestoreHelpers,\n type FirebaseInstance,\n type FirestoreDB,\n type CallableFunction,\n} from '@core/types/firebase.types'\nimport { type Firestore } from 'firebase/firestore'\n\nimport { api } from './firebase/api'\n\nexport type FsClient = ReturnType<typeof createFsClientBase>\n\nexport type FsClientParams = Omit<Parameters<typeof createFsClientBase>[0], 'helpers'>\n\nexport function createFsClientBase({\n db,\n helpers,\n httpsCallable,\n logEvent,\n}: {\n db: FirebaseInstance\n helpers: FirestoreHelpers\n httpsCallable: (name: string) => CallableFunction\n logEvent: (name: string, data: any) => void\n}) {\n const dbAsFirestore = db as FirestoreDB\n\n api.initialize({\n db: dbAsFirestore as Firestore,\n helpers,\n httpsCallable,\n logEvent,\n })\n\n return {\n assignmentRepo: createAssignmentRepo(),\n cardRepo: createCardRepo(),\n }\n}\n"],"mappings":"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","names":["query","orderBy","limit","startAt","startAfter","endAt","endBefore","where","increment","doc","collection","writeBatch","serverTimestamp","setDoc","getDoc","getDocs","addDoc","updateDoc","deleteDoc","runTransaction","useQuery","dayjs","dayjs","serverTimestamp","score","dayjs","dayjs","dayjs","serverTimestamp","dayjs","useQuery","createNotification","useMutation","useQuery","ActivityPageType","FeedbackTypesCard","LeniencyCard","VerificationCardStatus","writeBatch","doc","query","useMutation","useQuery","useQuery","useQuery","useEffect","v4","doc","serverTimestamp","setDoc","submitAssignmentScore","submitPracticeScore","_a","_b","serverTimestamp","useEffect","useQuery","query","useQuery","query","useQuery","limit","where","useMutation","serverTimestamp","increment","useQuery","query","_a","_b","_c","getTranscript"]}
1
+ {"version":3,"sources":["../src/providers/SpeakableProvider.tsx","../src/utils/error-handler.ts","../src/lib/firebase/api.ts","../src/domains/assignment/assignment.constants.ts","../src/domains/assignment/services/get-assignments-score.service.ts","../src/domains/assignment/services/attach-score-assignment.service.ts","../src/domains/assignment/services/get-all-assignment.service.ts","../src/domains/assignment/utils/check-assignment-availability.ts","../src/domains/assignment/services/get-assignment.service.ts","../src/domains/assignment/assignment.repo.ts","../src/domains/assignment/hooks/assignment.hooks.ts","../src/domains/assignment/hooks/score-hooks.ts","../src/utils/debounce.utils.ts","../src/lib/tanstack/handle-optimistic-update-query.ts","../src/constants/speakable-plans.ts","../src/hooks/usePermissions.ts","../src/domains/notification/notification.constants.ts","../src/domains/notification/services/create-notification.service.ts","../src/constants/web.constants.ts","../src/domains/notification/services/send-notification.service.ts","../src/domains/notification/hooks/notification.hooks.ts","../src/hooks/useGoogleClassroom.ts","../src/lib/firebase/firebase-analytics/grading-standard.ts","../src/constants/analytics.constants.ts","../src/lib/firebase/firebase-analytics/assignment.ts","../src/domains/assignment/utils/create-default-score.ts","../src/domains/assignment/score-practice.constants.ts","../src/domains/assignment/services/create-score.service.ts","../src/domains/assignment/services/get-score.service.ts","../src/domains/assignment/utils/calculateScoreAndProgress.ts","../src/domains/assignment/services/update-score.service.ts","../src/domains/assignment/services/clear-score.service.ts","../src/domains/assignment/services/submit-assignment-score.service.ts","../src/domains/cards/card.hooks.ts","../src/domains/cards/card.model.ts","../src/domains/cards/card.constants.ts","../src/domains/cards/services/get-card.service.ts","../src/domains/cards/services/create-card.service.ts","../src/utils/text-utils.ts","../src/domains/cards/services/get-card-verification-status.service.ts","../src/domains/cards/card.repo.ts","../src/domains/cards/utils/check-page-type.ts","../src/domains/cards/utils/get-page-prompt.ts","../src/domains/cards/utils/get-completed-pages.ts","../src/domains/cards/utils/get-label-page.ts","../src/domains/cards/utils/get-page-media-data.ts","../src/domains/sets/set.hooks.ts","../src/domains/sets/set.constants.ts","../src/domains/sets/services/get-set.service.ts","../src/domains/sets/set.repo.ts","../src/utils/ai/detect-transcript-hallucionation.ts","../src/utils/ai/get-transcript.ts","../src/constants/all-langs.json","../src/utils/ai/get-respond-card-tool.ts","../src/hooks/useActivity.ts","../src/services/add-grading-standard.ts","../src/hooks/useActivityTracker.ts","../src/hooks/useCredits.ts","../src/hooks/useOrganizationAccess.ts","../src/hooks/useSpeakableTranscript.ts","../src/hooks/useUpdateStudentVoc.ts","../src/hooks/useActivityFeedbackAccess.ts","../src/hooks/useOpenAI.ts","../src/lib/create-firebase-client-native.ts","../src/lib/create-firebase-client.ts"],"sourcesContent":["import React, { createContext, useContext, useEffect, useState } from 'react'\nimport { type QueryClient } from '@tanstack/react-query'\nimport { type FsClient } from '@core/lib/create-firebase-client'\nimport { type User } from '@core/types/user.types'\nimport { type Permissions } from '@core/types/permissions.types'\n\ninterface FsContext {\n speakableApi: Awaited<FsClient>\n queryClient: QueryClient\n user: User\n permissions: Permissions\n}\n\nexport const FsCtx = createContext<FsContext | null>(null)\n\nexport function SpeakableProvider({\n user,\n children,\n queryClient,\n permissions,\n fsClient,\n}: {\n children: React.ReactNode\n fsClient: FsClient\n permissions: Permissions\n queryClient: QueryClient\n user: User\n}) {\n const [speakableApi, setSpeakableApi] = useState<null | Awaited<FsClient>>(null)\n\n useEffect(() => {\n setSpeakableApi(fsClient)\n }, [fsClient])\n\n if (!speakableApi) return null\n\n return (\n <FsCtx.Provider\n value={{\n speakableApi,\n queryClient,\n user,\n permissions,\n }}\n >\n {children}\n </FsCtx.Provider>\n )\n}\n\nexport function useSpeakableApi() {\n const ctx = useContext(FsCtx)\n\n if (!ctx) throw new Error('useSpeakableApi must be used within a SpeakableProvider')\n\n return ctx\n}\n","// error-handler.ts\nimport { type FirebaseError } from 'firebase/app'\n\nexport class ServiceError extends Error {\n constructor(\n message: string,\n public readonly originalError?: unknown,\n public readonly code?: string,\n ) {\n super(message)\n this.name = 'ServiceError'\n }\n}\n\n// Preservamos los tipos de los parámetros\ntype AsyncFunction<T, P extends any[] = any[]> = (...args: P) => Promise<T>\n\nexport function withErrorHandler<T, P extends any[]>(\n fn: AsyncFunction<T, P>,\n serviceName: string,\n): AsyncFunction<T, P> {\n return async (...args: P): Promise<T> => {\n try {\n return await fn(...args)\n } catch (error) {\n // Log the error for debugging\n console.error(`Service ${serviceName} failed with args:`, args)\n console.error('Error details:', error)\n \n if (error instanceof Error && 'code' in error) {\n const firebaseError = error as FirebaseError\n\n throw new ServiceError(\n `Error in ${serviceName}: ${firebaseError.message}`,\n error,\n firebaseError.code,\n )\n }\n\n if (error instanceof Error) {\n throw new ServiceError(`Error in ${serviceName}: ${error.message}`, error)\n }\n\n throw new ServiceError(`Unknown error in ${serviceName}`, error)\n }\n }\n}\n","import { type CallableFunction, type FirestoreHelpers } from '@core/types/firebase.types'\nimport {\n type SetOptions,\n type DocumentData,\n type QueryConstraint,\n type WithFieldValue,\n type Firestore,\n} from 'firebase/firestore'\n\ninterface FirebaseConfig {\n db: Firestore\n helpers: FirestoreHelpers\n httpsCallable: (name: string) => CallableFunction\n logEvent: (name: string, data: any) => void\n}\n\ntype FirebasePath = string\n\nexport class FirebaseAPI {\n private static instance: FirebaseAPI\n private config: FirebaseConfig | null = null\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private constructor() {\n // Private constructor for singleton pattern\n }\n\n static getInstance(): FirebaseAPI {\n if (!FirebaseAPI.instance) {\n FirebaseAPI.instance = new FirebaseAPI()\n }\n\n return FirebaseAPI.instance\n }\n\n initialize(config: FirebaseConfig) {\n this.config = config\n }\n\n get db() {\n if (!this.config) throw new Error('Firebase API not initialized')\n\n return this.config.db\n }\n\n get helpers() {\n if (!this.config) throw new Error('Firebase API not initialized')\n\n return this.config.helpers\n }\n\n get httpsCallable() {\n return this.config?.httpsCallable\n }\n\n logEvent(name: string, data: any) {\n this.config?.logEvent(name, data)\n }\n\n accessQueryConstraints() {\n const { query, orderBy, limit, startAt, startAfter, endAt, endBefore, where, increment } =\n this.helpers\n\n return {\n query,\n orderBy,\n limit,\n startAt,\n startAfter,\n endAt,\n endBefore,\n where,\n increment,\n }\n }\n\n accessHelpers() {\n const { doc, collection, writeBatch, serverTimestamp, setDoc } = this.helpers\n\n return {\n doc: (path: FirebasePath) => doc(this.db, path),\n collection: (path: FirebasePath) => collection(this.db, path),\n writeBatch: () => writeBatch(this.db),\n serverTimestamp: serverTimestamp,\n setDoc: setDoc,\n }\n }\n\n async getDoc<T>(path: FirebasePath) {\n const { getDoc, doc } = this.helpers\n\n const docRef = doc(this.db, path)\n const docSnap = await getDoc(docRef)\n\n const data = docSnap.exists()\n ? ({\n ...docSnap.data(),\n id: docSnap.id,\n } as T)\n : null\n\n return {\n id: docSnap.id,\n data,\n }\n }\n\n async getDocs<T>(path: FirebasePath, ...queryConstraints: QueryConstraint[]) {\n const { getDocs, query, collection } = this.helpers\n const collectionRef = collection(this.db, path)\n const q =\n queryConstraints.length > 0 ? query(collectionRef, ...queryConstraints) : collectionRef\n\n const querySnapshot = await getDocs(q)\n\n const data = querySnapshot.docs.map(doc => ({\n data: doc.data() as T,\n id: doc.id,\n }))\n\n return {\n data: data as unknown as (T & {\n id: string\n })[],\n querySnapshot,\n empty: querySnapshot.empty,\n }\n }\n\n async addDoc<T extends WithFieldValue<DocumentData>>(\n path: FirebasePath,\n data: T,\n ): Promise<{ id: string } & T> {\n const { addDoc, collection } = this.helpers\n const collectionRef = collection(this.db, path)\n const docRef = await addDoc(collectionRef, data)\n\n return {\n ...data,\n id: docRef.id,\n }\n }\n\n async setDoc<T extends WithFieldValue<DocumentData>>(\n path: FirebasePath,\n data: T,\n options: SetOptions = {},\n ): Promise<void> {\n const { setDoc, doc } = this.helpers\n const docRef = doc(this.db, path)\n\n await setDoc(docRef, data, options)\n }\n\n async updateDoc(path: FirebasePath, data: any): Promise<void> {\n const { updateDoc, doc } = this.helpers\n\n const docRef = doc(this.db, path)\n\n await updateDoc(docRef, data)\n }\n\n async deleteDoc(path: FirebasePath): Promise<void> {\n const { deleteDoc, doc } = this.helpers\n const docRef = doc(this.db, path)\n\n await deleteDoc(docRef)\n }\n\n async runTransaction<T>(updateFunction: (transaction: any) => Promise<T>): Promise<T> {\n const { runTransaction } = this.helpers\n\n return runTransaction(this.db, updateFunction)\n }\n\n async runBatch(operations: (() => Promise<void>)[]): Promise<void> {\n const { writeBatch } = this.helpers\n const batch = writeBatch(this.db)\n\n await Promise.all(operations.map(op => op()))\n await batch.commit()\n }\n\n writeBatch() {\n const { writeBatch } = this.helpers\n\n const batch = writeBatch(this.db)\n\n return batch\n }\n}\n\nexport const api = FirebaseAPI.getInstance()\n","export enum AssignmentAnalyticsType {\n Macro = 'macro',\n Gradebook = 'gradebook',\n Cards = 'cards',\n Student = 'student',\n StudentSummary = 'student_summary',\n All = 'all',\n}\n\nexport const ASSIGNMENT_ANALYTICS_TYPES = [\n AssignmentAnalyticsType.Macro,\n AssignmentAnalyticsType.Gradebook,\n AssignmentAnalyticsType.Cards,\n AssignmentAnalyticsType.Student,\n AssignmentAnalyticsType.StudentSummary,\n]\n\nconst ASSIGNMENTS_COLLECTION = 'assignments'\nconst ANALYTICS_SUBCOLLECTION = 'analytics'\nconst SCORES_SUBCOLLECTION = 'scores'\n\nexport type RefsAssignmentFiresotre =\n `${typeof ASSIGNMENTS_COLLECTION}/${string}${`/${typeof ANALYTICS_SUBCOLLECTION}/${string}` | `/${typeof SCORES_SUBCOLLECTION}/${string}` | ''}`\n\nexport const refsAssignmentFiresotre = {\n allAssignments: () => ASSIGNMENTS_COLLECTION,\n assignment: (params: { id: string }) => `${ASSIGNMENTS_COLLECTION}/${params.id}` as const,\n assignmentAllAnalytics: (params: { id: string }) =>\n `${ASSIGNMENTS_COLLECTION}/${params.id}/${ANALYTICS_SUBCOLLECTION}` as const,\n assignmentAnalytics: (params: { id: string; type: string }) =>\n `${ASSIGNMENTS_COLLECTION}/${params.id}/${ANALYTICS_SUBCOLLECTION}/${params.type}` as const,\n assignmentScores: (params: { id: string; userId: string }) =>\n `${ASSIGNMENTS_COLLECTION}/${params.id}/${SCORES_SUBCOLLECTION}/${params.userId}` as const,\n}\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport {\n ASSIGNMENT_ANALYTICS_TYPES,\n AssignmentAnalyticsType,\n refsAssignmentFiresotre,\n} from '../assignment.constants'\n\nconst _getAssignmentScores = async ({\n assignmentId,\n analyticType = AssignmentAnalyticsType.Macro,\n studentId,\n currentUserId,\n}: {\n assignmentId: string\n currentUserId: string\n analyticType?: AssignmentAnalyticsType\n studentId?: string\n}) => {\n if (analyticType === AssignmentAnalyticsType.Student) {\n const path = refsAssignmentFiresotre.assignmentScores({\n id: assignmentId,\n userId: currentUserId,\n })\n const response = await api.getDoc(path)\n\n return { scores: response.data, id: assignmentId }\n }\n\n if (analyticType === AssignmentAnalyticsType.StudentSummary && studentId) {\n const path = refsAssignmentFiresotre.assignmentScores({\n id: assignmentId,\n userId: studentId,\n })\n const response = await api.getDoc(path)\n\n return { scores: response.data, id: assignmentId }\n }\n\n if (\n analyticType !== AssignmentAnalyticsType.All &&\n ASSIGNMENT_ANALYTICS_TYPES.includes(analyticType)\n ) {\n const ref = refsAssignmentFiresotre.assignmentAnalytics({\n id: assignmentId,\n type: analyticType,\n })\n\n const docData = await api.getDoc(ref)\n\n return { scores: docData.data, id: assignmentId }\n } else if (analyticType === AssignmentAnalyticsType.All) {\n const ref = refsAssignmentFiresotre.assignmentAllAnalytics({ id: assignmentId })\n\n const response = await api.getDocs(ref)\n const data = response.data.reduce((acc, curr) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n acc[curr.id] = curr\n\n return acc\n }, {})\n\n return { scores: data, id: assignmentId }\n }\n}\n\nexport const getAssignmentScores = withErrorHandler(_getAssignmentScores, 'getAssignmentScores')\n","import { withErrorHandler } from '@core/utils/error-handler'\n\nimport { type AssignmentAnalyticsType } from '../assignment.constants'\nimport { type AssignmentWithId } from '../assignment.model'\n\nimport { getAssignmentScores } from './get-assignments-score.service'\n\nconst _attachScoresAssignment = async ({\n assignments,\n analyticType,\n studentId,\n currentUserId,\n}: {\n assignments: AssignmentWithId[]\n analyticType: AssignmentAnalyticsType\n studentId?: string\n currentUserId: string\n}) => {\n const scoresPromises = assignments.map(a => {\n return getAssignmentScores({\n assignmentId: a.id,\n analyticType: analyticType,\n studentId,\n currentUserId,\n })\n })\n const scores = await Promise.all(scoresPromises)\n\n const scoresObject = scores.reduce((acc, curr) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n acc[curr.id] = curr.scores\n\n return acc\n }, {})\n const assignmentsWithScores = assignments.map(a => {\n return {\n ...a,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/ban-ts-comment\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n scores: scoresObject[a.id] ?? null,\n }\n })\n\n return assignmentsWithScores\n}\n\nexport const attachScoresAssignment = withErrorHandler(\n _attachScoresAssignment,\n 'attachScoresAssignment',\n)\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { type AssignmentWithId } from '../assignment.model'\n\nexport async function _getAllAssignments() {\n const path = refsAssignmentFiresotre.allAssignments()\n const response = await api.getDocs<AssignmentWithId>(path)\n\n return response.data\n}\n\nexport const getAllAssignments = withErrorHandler(_getAllAssignments, 'getAllAssignments')\n","import { type CustomTimestamp } from '@core/types/firebase.types'\nimport dayjs from 'dayjs'\n\nexport const checkAssignmentAvailability = (\n scheduledTime: string | CustomTimestamp | null | undefined,\n) => {\n if (!scheduledTime) return true\n\n const scheduledDate =\n typeof scheduledTime === 'string' ? dayjs(scheduledTime) : dayjs(scheduledTime.toDate())\n\n if (!scheduledDate.isValid()) return true\n\n return dayjs().isAfter(scheduledDate)\n}\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { type AssignmentWithId } from '../assignment.model'\nimport { type AssignmentAnalyticsType, refsAssignmentFiresotre } from '../assignment.constants'\nimport { checkAssignmentAvailability } from '../utils/check-assignment-availability'\n\nimport { attachScoresAssignment } from './attach-score-assignment.service'\n\nasync function _getAssignment(params: {\n assignmentId: string\n currentUserId: string\n analyticType?: AssignmentAnalyticsType\n studentId?: string\n}) {\n const path = refsAssignmentFiresotre.assignment({ id: params.assignmentId })\n const response = await api.getDoc<AssignmentWithId>(path)\n\n if (!response.data) return null\n\n const assignment = response.data\n\n const isAvailable = checkAssignmentAvailability(assignment.scheduledTime)\n\n const assignmentWithId: AssignmentWithId = {\n ...assignment,\n isAvailable,\n id: params.assignmentId,\n scheduledTime: assignment.scheduledTime ?? null,\n }\n\n if (params.analyticType) {\n const assignmentsWithScores = await attachScoresAssignment({\n assignments: [assignmentWithId],\n analyticType: params.analyticType,\n currentUserId: params.currentUserId,\n })\n\n return assignmentsWithScores.length > 0 ? assignmentsWithScores[0] : assignmentWithId\n }\n\n return assignmentWithId\n}\n\nexport const getAssignment = withErrorHandler(_getAssignment, 'getAssignment')\n","import { attachScoresAssignment } from './services/attach-score-assignment.service'\nimport { getAllAssignments } from './services/get-all-assignment.service'\nimport { getAssignment } from './services/get-assignment.service'\nimport { getAssignmentScores } from './services/get-assignments-score.service'\n\nexport const createAssignmentRepo = () => {\n return {\n getAssignment: getAssignment,\n attachScoresAssignment: attachScoresAssignment,\n getAssignmentScores: getAssignmentScores,\n getAllAssignments: getAllAssignments,\n }\n}\n","import { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { useQuery } from '@tanstack/react-query'\n\nimport { type AssignmentAnalyticsType } from '../assignment.constants'\n\nexport const assignmentQueryKeys = {\n all: ['assignments'] as const,\n byId: (id: string) => [...assignmentQueryKeys.all, id] as const,\n list: () => [...assignmentQueryKeys.all, 'list'] as const,\n}\n\nexport function useAssignment({\n assignmentId,\n enabled = true,\n analyticType,\n userId,\n}: {\n assignmentId: string\n enabled?: boolean\n analyticType?: AssignmentAnalyticsType\n userId: string\n}) {\n const { speakableApi } = useSpeakableApi()\n\n return useQuery({\n queryKey: assignmentQueryKeys.byId(assignmentId),\n queryFn: () =>\n speakableApi.assignmentRepo.getAssignment({\n assignmentId: assignmentId,\n analyticType,\n currentUserId: userId,\n }),\n enabled,\n })\n}\n","import { useMutation, useQuery } from '@tanstack/react-query'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { type PageActivity } from '@core/domains/cards'\nimport { debounce } from '@core/utils/debounce.utils'\nimport { handleOptimisticUpdate } from '@core/lib/tanstack/handle-optimistic-update-query'\nimport usePermissions from '@core/hooks/usePermissions'\nimport { SpeakableNotificationTypes, useCreateNotification } from '@core/domains/notification'\nimport { useGoogleClassroom } from '@core/hooks/useGoogleClassroom'\nimport { logSubmitAssignment } from '@core/lib/firebase/firebase-analytics'\n\nimport { getScore } from '../services/get-score.service'\nimport { type Score, type PageScore } from '../assignment.model'\nimport calculateScoreAndProgress from '../utils/calculateScoreAndProgress'\nimport { updateCardScore, updateScore } from '../services/update-score.service'\nimport { clearScore, clearScoreV2 } from '../services/clear-score.service'\nimport {\n submitAssignmentScore,\n submitPracticeScore,\n} from '../services/submit-assignment-score.service'\n\nexport const scoreQueryKeys = {\n all: ['scores'] as const,\n byId: (id: string) => [...scoreQueryKeys.all, id] as const,\n list: () => [...scoreQueryKeys.all, 'list'] as const,\n}\n\nexport function useScore({\n isAssignment,\n activityId,\n userId = '',\n courseId,\n enabled = true,\n googleClassroomUserId,\n}: {\n userId: string\n isAssignment: boolean\n activityId: string\n courseId?: string\n enabled?: boolean\n googleClassroomUserId?: string\n}) {\n return useQuery({\n queryFn: () =>\n getScore({\n userId,\n courseId,\n activityId,\n googleClassroomUserId,\n isAssignment,\n }),\n queryKey: scoreQueryKeys.byId(activityId),\n enabled,\n })\n}\n\n// Reduce debounce time to prevent data loss and add better error handling\nconst debounceUpdateScore = debounce(updateScore, 500)\n\nexport function useUpdateScore() {\n const { queryClient } = useSpeakableApi()\n\n const mutation = useMutation({\n mutationFn: debounceUpdateScore,\n onMutate: variables => {\n return handleOptimisticUpdate({\n queryClient,\n queryKey: scoreQueryKeys.byId(variables.activityId),\n newData: variables.data,\n })\n },\n onError: (_, variables, context) => {\n if (context?.previousData)\n queryClient.setQueryData(scoreQueryKeys.byId(variables.activityId), context.previousData)\n },\n onSettled: (_, err, variables) => {\n queryClient.invalidateQueries({\n queryKey: scoreQueryKeys.byId(variables.activityId),\n })\n },\n })\n\n return {\n mutationUpdateScore: mutation,\n }\n}\n\nexport function useUpdateCardScore({\n isAssignment,\n activityId,\n userId,\n cardIds,\n weights,\n}: {\n isAssignment: boolean\n userId: string\n activityId: string\n cardIds: string[]\n weights: Record<string, number>\n}) {\n const { queryClient } = useSpeakableApi()\n\n const queryKey = scoreQueryKeys.byId(activityId)\n\n const mutation = useMutation({\n mutationFn: async ({ cardId, cardScore }: { cardId: string; cardScore: PageScore }) => {\n const previousScores = queryClient.getQueryData<Score>(queryKey)\n\n const { progress, score, newScoreUpdated, updatedCardScore } = getScoreUpdated({\n previousScores: previousScores ?? {},\n cardId,\n cardScore,\n cardIds,\n weights,\n })\n\n await updateCardScore({\n userId,\n cardId,\n isAssignment,\n activityId,\n updates: {\n cardScore: updatedCardScore,\n progress,\n score,\n },\n })\n\n return { cardId, scoresUpdated: newScoreUpdated }\n },\n onMutate: ({ cardId, cardScore }) => {\n // Store previous data before updating\n const previousData = queryClient.getQueryData<Score>(queryKey)\n\n queryClient.setQueryData(queryKey, (previousScore: Partial<Score> | undefined) => {\n const updates = handleOptimisticScore({\n score: previousScore,\n cardId,\n cardScore,\n cardIds,\n weights,\n })\n\n return {\n ...previousScore,\n ...updates,\n }\n })\n\n // Return context with previous data for error recovery\n return { previousData }\n },\n onError: (error, variables, context) => {\n // eslint-disable-next-line no-console\n console.log('Error updating card score:', error.message)\n\n // Revert to previous data if available\n if (context?.previousData) {\n queryClient.setQueryData(queryKey, context.previousData)\n }\n },\n onSettled: () => {\n // Ensure data is fresh after mutation completes\n queryClient.invalidateQueries({\n queryKey,\n })\n },\n })\n\n return {\n mutationUpdateCardScore: mutation,\n }\n}\n\nconst getScoreUpdated = ({\n cardId,\n cardScore,\n previousScores,\n cardIds,\n weights,\n}: {\n previousScores: Partial<Score>\n cardId: string\n cardScore: PageScore\n cardIds: string[]\n weights: Record<string, number>\n}) => {\n const previousCard = previousScores.cards?.[cardId]\n\n const newCardScore = {\n ...(previousCard ?? {}),\n ...cardScore,\n } as PageActivity\n\n const newScores = {\n ...previousScores,\n cards: {\n ...(previousScores.cards ?? {}),\n [cardId]: newCardScore,\n },\n } as Score\n\n const { score, progress } = calculateScoreAndProgress(newScores, cardIds, weights)\n\n return {\n newScoreUpdated: newScores,\n updatedCardScore: cardScore,\n score,\n progress,\n }\n}\n\nconst handleOptimisticScore = ({\n score,\n cardId,\n cardScore,\n cardIds,\n weights,\n}: {\n score: Partial<Score> | undefined\n cardId: string\n cardScore: PageScore\n cardIds: string[]\n weights: Record<string, number>\n}) => {\n let cards = { ...(score?.cards ?? {}) }\n\n cards = {\n ...cards,\n [cardId]: {\n ...cards[cardId],\n ...cardScore,\n },\n }\n const { score: scoreValue, progress } = calculateScoreAndProgress(\n // @ts-ignore\n {\n ...(score ?? {}),\n cards,\n },\n cardIds,\n weights,\n )\n\n return { cards, score: scoreValue, progress }\n}\n\nexport function useClearScore() {\n const { queryClient } = useSpeakableApi()\n\n const mutation = useMutation({\n mutationFn: clearScore,\n onError: error => {\n // eslint-disable-next-line no-console\n console.log('Error clearing score:', error.message)\n },\n onSettled: result => {\n queryClient.invalidateQueries({\n queryKey: scoreQueryKeys.byId(result?.activityId ?? ''),\n })\n },\n })\n\n return {\n mutationClearScore: mutation,\n }\n}\n\nexport function useClearScoreV2() {\n const { queryClient } = useSpeakableApi()\n\n const mutation = useMutation({\n mutationFn: clearScoreV2,\n onError: error => {\n // eslint-disable-next-line no-console\n console.log('Error clearing score V2:', error.message)\n },\n onSettled: result => {\n queryClient.invalidateQueries({\n queryKey: scoreQueryKeys.byId(result?.activityId ?? ''),\n })\n },\n })\n\n return {\n mutationClearScore: mutation,\n }\n}\n\nexport function useSubmitAssignmentScore({\n onAssignmentSubmitted,\n studentName,\n}: {\n onAssignmentSubmitted: (assignmentId: string) => void\n studentName: string\n}) {\n const { queryClient } = useSpeakableApi()\n\n const { hasGoogleClassroomGradePassback } = usePermissions()\n const { submitAssignmentToGoogleClassroom } = useGoogleClassroom()\n const { createNotification } = useCreateNotification()\n\n const mutation = useMutation({\n mutationFn: async ({\n assignment,\n userId,\n cardIds,\n weights,\n scores,\n status,\n }: {\n assignment: {\n id: string\n name: string\n owners: string[]\n courseId: string\n courseWorkId: string\n isAssessment: boolean\n maxPoints: number\n }\n userId: string\n cardIds: string[]\n weights: Record<string, number>\n scores: Score\n status: Score['status']\n // activeCardId: string\n }) => {\n try {\n const scoreUpdated = await submitAssignmentScore({\n assignment,\n userId,\n cardIds,\n weights,\n status,\n studentName: studentName,\n })\n\n if (\n assignment.courseWorkId != null &&\n !assignment.isAssessment &&\n hasGoogleClassroomGradePassback\n ) {\n await submitAssignmentToGoogleClassroom({\n assignment,\n scores,\n })\n }\n\n if (assignment.isAssessment) {\n // New assessment submitted email\n // const data = assessmentSubmittedEmail({\n // studentName: user?.displayName,\n // studentId: userId,\n // teacherName: '!',\n // assignmentId: assignment.id,\n // assignmentTitle: assignment.name,\n // })\n\n // sendEmail(user?.email, data)\n // @ts-ignore\n createNotification(SpeakableNotificationTypes.ASSESSMENT_SUBMITTED, assignment)\n }\n\n if (assignment?.id) {\n logSubmitAssignment({\n courseId: assignment?.courseId,\n })\n }\n\n onAssignmentSubmitted(assignment.id)\n\n queryClient.setQueryData(scoreQueryKeys.byId(assignment.id), {\n ...scores,\n ...scoreUpdated.fieldsUpdated,\n })\n\n return {\n success: true,\n message: 'Score submitted successfully',\n }\n } catch (error) {\n return {\n success: false,\n error: error,\n }\n }\n },\n })\n\n return {\n submitAssignmentScore: mutation.mutateAsync,\n isLoading: mutation.isPending,\n }\n}\n\nexport function useSubmitPracticeScore() {\n const { queryClient } = useSpeakableApi()\n\n const mutation = useMutation({\n mutationFn: async ({\n setId,\n userId,\n scores,\n }: {\n setId: string\n userId: string\n scores: Score\n }) => {\n try {\n await submitPracticeScore({\n setId,\n userId,\n scores,\n })\n\n queryClient.invalidateQueries({\n queryKey: scoreQueryKeys.byId(setId),\n })\n\n return {\n success: true,\n message: 'Score submitted successfully',\n }\n } catch (error) {\n return {\n success: false,\n error: error,\n }\n }\n },\n })\n\n return {\n submitPracticeScore: mutation.mutateAsync,\n isLoading: mutation.isPending,\n }\n}\n","/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\nexport function debounce<T extends (...args: any[]) => Promise<any>>(func: T, waitFor: number) {\n let timeoutId: NodeJS.Timeout | null\n\n return (...args: Parameters<T>): Promise<ReturnType<T>> =>\n new Promise((resolve, reject) => {\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n timeoutId = setTimeout(async () => {\n try {\n const result = await func(...args)\n\n resolve(result)\n } catch (error) {\n reject(error)\n }\n }, waitFor)\n })\n}\n","import { type QueryClient, type QueryKey } from '@tanstack/react-query'\n\nexport const handleOptimisticUpdate = async <T>({\n queryClient,\n queryKey,\n newData,\n}: {\n queryClient: QueryClient\n queryKey: QueryKey\n newData: T\n}) => {\n await queryClient.cancelQueries({\n queryKey,\n })\n\n const previousData = queryClient.getQueryData<T>(queryKey)\n\n if (previousData === undefined) {\n queryClient.setQueryData(queryKey, newData)\n } else {\n queryClient.setQueryData(queryKey, { ...previousData, ...newData })\n }\n\n return { previousData }\n}\n","export const FEEDBACK_PLANS = {\n FEEDBACK_TRANSCRIPT: 'FEEDBACK_TRANSCRIPT', // Transcript from the audio\n FEEDBACK_SUMMARY: 'FEEDBACK_SUMMARY', // Chatty summary (Free plan)\n FEEDBACK_GRAMMAR_INSIGHTS: 'FEEDBACK_GRAMMAR_INSIGHTS', // Grammar insights\n FEEDBACK_SUGGESTED_RESPONSE: 'FEEDBACK_SUGGESTED_RESPONSE', // Suggested Response\n FEEDBACK_RUBRIC: 'FEEDBACK_RUBRIC', // Suggested Response\n FEEDBACK_GRADING_STANDARDS: 'FEEDBACK_GRADING_STANDARDS', // ACTFL / WIDA Estimate\n FEEDBACK_TARGET_LANGUAGE: 'FEEDBACK_TARGET_LANGUAGE', // Ability to set the feedback language to the target language of the student\n FEEDBACK_DISABLE_ALLOW_RETRIES: 'FEEDBACK_DISABLE_ALLOW_RETRIES', // Turn of allow retries\n} as const\n\nexport const AUTO_GRADING_PLANS = {\n AUTO_GRADING_PASS_FAIL: 'AUTO_GRADING_PASS_FAIL', // Pass / fail grading\n AUTO_GRADING_RUBRICS: 'AUTO_GRADING_RUBRICS', // Autograded rubrics\n AUTO_GRADING_STANDARDS_BASED: 'AUTO_GRADING_STANDARDS_BASED', // Standards based grading\n} as const\n\nexport const COMMENTS_PLANS = {\n COMMENTS_SUGGESTIONS: 'COMMENTS_SUGGESTIONS', // Comment suggestions\n} as const\n\nexport const AI_ASSISTANT_PLANS = {\n AI_ASSISTANT_DOCUMENT_UPLOADS: 'AI_ASSISTANT_DOCUMENT_UPLOADS', // Allow document uploading\n AI_ASSISTANT_UNLIMITED_USE: 'AI_ASSISTANT_UNLIMITED_USE', // Allow unlimited use of AI assistant. Otherwise, limits are used.\n} as const\n\nexport const ASSIGNMENT_SETTINGS_PLANS = {\n ASSESSMENTS: 'ASSESSMENTS', // Ability to create assessment assignment types\n GOOGLE_CLASSROOM_GRADE_PASSBACK: 'GOOGLE_CLASSROOM_GRADE_PASSBACK', // Assignment scores can sync with classroom\n} as const\n\nexport const ANALYTICS_PLANS = {\n ANALYTICS_GRADEBOOK: 'ANALYTICS_GRADEBOOK', // Access to the gradebook page\n ANALYTICS_CLASSROOM_ANALYTICS: 'ANALYTICS_CLASSROOM_ANALYTICS', // Access to the classroom analytics page\n ANALYTICS_STUDENT_PROGRESS_REPORTS: 'ANALYTICS_STUDENT_PROGRESS_REPORTS', // Access to the panel that shows an individual student's progress and assignments\n ANALYTICS_ASSIGNMENT_RESULTS: 'ANALYTICS_ASSIGNMENT_RESULTS', // Access to the assigment RESULTS page\n ANALYTICS_ORGANIZATION: 'ANALYTICS_ORGANIZATION', // Access to the organization analytics panel (for permitted admins)\n} as const\n\nexport const SPACES_PLANS = {\n SPACES_CREATE_SPACE: 'SPACES_CREATE_SPACE', // Ability to create spaces\n SPACES_CHECK_POINTS: 'SPACES_CHECK_POINTS', // Feature not available yet. Ability to create checkpoints for spaces for data aggregation\n} as const\n\nexport const DISCOVER_PLANS = {\n DISCOVER_ORGANIZATION_LIBRARY: 'DISCOVER_ORGANIZATION_LIBRARY', // Access to the organizations shared library\n} as const\n\nexport const INTEGRATIONS_PLANS = {\n INTEGRATIONS_LTI: 'INTEGRATIONS_LTI', //Access to all LTI integrations (Canvas, Blackboard, Schoology, etc)\n} as const\n\nexport const MEDIA_AREA_PLANS = {\n MEDIA_AREA_DOCUMENT_UPLOAD: 'MEDIA_AREA_DOCUMENT_UPLOAD',\n MEDIA_AREA_AUDIO_FILES: 'MEDIA_AREA_AUDIO_FILES',\n} as const\n\nexport const FREE_PLAN = []\n\nexport const TEACHER_PRO_PLAN = [\n FEEDBACK_PLANS.FEEDBACK_TRANSCRIPT,\n FEEDBACK_PLANS.FEEDBACK_SUMMARY,\n FEEDBACK_PLANS.FEEDBACK_TARGET_LANGUAGE,\n AUTO_GRADING_PLANS.AUTO_GRADING_PASS_FAIL,\n ANALYTICS_PLANS.ANALYTICS_GRADEBOOK,\n SPACES_PLANS.SPACES_CREATE_SPACE,\n // AUTO_GRADING_PLANS.AUTO_GRADING_STANDARDS_BASED,\n]\n\nexport const SCHOOL_STARTER = [\n FEEDBACK_PLANS.FEEDBACK_TRANSCRIPT,\n FEEDBACK_PLANS.FEEDBACK_SUMMARY,\n FEEDBACK_PLANS.FEEDBACK_GRAMMAR_INSIGHTS,\n FEEDBACK_PLANS.FEEDBACK_SUGGESTED_RESPONSE,\n FEEDBACK_PLANS.FEEDBACK_RUBRIC,\n FEEDBACK_PLANS.FEEDBACK_GRADING_STANDARDS,\n FEEDBACK_PLANS.FEEDBACK_DISABLE_ALLOW_RETRIES,\n FEEDBACK_PLANS.FEEDBACK_TARGET_LANGUAGE,\n AUTO_GRADING_PLANS.AUTO_GRADING_PASS_FAIL,\n AUTO_GRADING_PLANS.AUTO_GRADING_RUBRICS,\n AUTO_GRADING_PLANS.AUTO_GRADING_STANDARDS_BASED,\n AI_ASSISTANT_PLANS.AI_ASSISTANT_DOCUMENT_UPLOADS,\n AI_ASSISTANT_PLANS.AI_ASSISTANT_UNLIMITED_USE,\n // ASSIGNMENT_SETTINGS_PLANS.ASSESSMENTS,\n ASSIGNMENT_SETTINGS_PLANS.GOOGLE_CLASSROOM_GRADE_PASSBACK,\n ANALYTICS_PLANS.ANALYTICS_GRADEBOOK,\n ANALYTICS_PLANS.ANALYTICS_STUDENT_PROGRESS_REPORTS,\n ANALYTICS_PLANS.ANALYTICS_CLASSROOM_ANALYTICS,\n // ANALYTICS_PLANS.ANALYTICS_ORGANIZATION,\n SPACES_PLANS.SPACES_CREATE_SPACE,\n SPACES_PLANS.SPACES_CHECK_POINTS,\n // DISCOVER_PLANS.DISCOVER_ORGANIZATION_LIBRARY,\n MEDIA_AREA_PLANS.MEDIA_AREA_DOCUMENT_UPLOAD,\n MEDIA_AREA_PLANS.MEDIA_AREA_AUDIO_FILES,\n]\n\nexport const ORGANIZATION_PLAN = [\n FEEDBACK_PLANS.FEEDBACK_TRANSCRIPT,\n FEEDBACK_PLANS.FEEDBACK_SUMMARY,\n FEEDBACK_PLANS.FEEDBACK_GRAMMAR_INSIGHTS,\n FEEDBACK_PLANS.FEEDBACK_SUGGESTED_RESPONSE,\n FEEDBACK_PLANS.FEEDBACK_RUBRIC,\n FEEDBACK_PLANS.FEEDBACK_GRADING_STANDARDS,\n FEEDBACK_PLANS.FEEDBACK_DISABLE_ALLOW_RETRIES,\n FEEDBACK_PLANS.FEEDBACK_TARGET_LANGUAGE,\n AUTO_GRADING_PLANS.AUTO_GRADING_PASS_FAIL,\n AUTO_GRADING_PLANS.AUTO_GRADING_RUBRICS,\n AUTO_GRADING_PLANS.AUTO_GRADING_STANDARDS_BASED,\n AI_ASSISTANT_PLANS.AI_ASSISTANT_DOCUMENT_UPLOADS,\n AI_ASSISTANT_PLANS.AI_ASSISTANT_UNLIMITED_USE,\n ASSIGNMENT_SETTINGS_PLANS.ASSESSMENTS,\n ASSIGNMENT_SETTINGS_PLANS.GOOGLE_CLASSROOM_GRADE_PASSBACK,\n ANALYTICS_PLANS.ANALYTICS_GRADEBOOK,\n ANALYTICS_PLANS.ANALYTICS_STUDENT_PROGRESS_REPORTS,\n ANALYTICS_PLANS.ANALYTICS_CLASSROOM_ANALYTICS,\n ANALYTICS_PLANS.ANALYTICS_ORGANIZATION,\n SPACES_PLANS.SPACES_CREATE_SPACE,\n SPACES_PLANS.SPACES_CHECK_POINTS,\n DISCOVER_PLANS.DISCOVER_ORGANIZATION_LIBRARY,\n MEDIA_AREA_PLANS.MEDIA_AREA_DOCUMENT_UPLOAD,\n MEDIA_AREA_PLANS.MEDIA_AREA_AUDIO_FILES,\n]\n\nexport const SpeakablePlanTypes = {\n basic: 'basic',\n teacher_pro: 'teacher_pro',\n school_starter: 'school_starter',\n organization: 'organization',\n // OLD PLANS\n starter: 'starter',\n growth: 'growth',\n professional: 'professional',\n} as const\n\nexport const SpeakablePermissionsMap = {\n [SpeakablePlanTypes.basic]: FREE_PLAN,\n [SpeakablePlanTypes.starter]: TEACHER_PRO_PLAN,\n [SpeakablePlanTypes.teacher_pro]: TEACHER_PRO_PLAN,\n [SpeakablePlanTypes.growth]: ORGANIZATION_PLAN,\n [SpeakablePlanTypes.professional]: ORGANIZATION_PLAN,\n [SpeakablePlanTypes.organization]: ORGANIZATION_PLAN,\n [SpeakablePlanTypes.school_starter]: SCHOOL_STARTER,\n} as const\n\nexport const SpeakablePlanHierarchy = [\n SpeakablePlanTypes.basic,\n SpeakablePlanTypes.starter,\n SpeakablePlanTypes.teacher_pro,\n SpeakablePlanTypes.growth,\n SpeakablePlanTypes.professional,\n SpeakablePlanTypes.school_starter,\n SpeakablePlanTypes.organization,\n] as const\n","import { ANALYTICS_PLANS, ASSIGNMENT_SETTINGS_PLANS } from '@core/constants/speakable-plans'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\n\nconst usePermissions = () => {\n const { permissions } = useSpeakableApi()\n\n const has = (permission: string) => permissions.permissions?.includes(permission)\n\n return {\n plan: permissions.plan,\n permissionsLoaded: permissions.loaded,\n isStripePlan: permissions.isStripePlan,\n refreshDate: permissions.refreshDate,\n isInstitutionPlan: permissions.isInstitutionPlan,\n subscriptionId: permissions.subscriptionId,\n contact: permissions.contact,\n hasGradebook: has(ANALYTICS_PLANS.ANALYTICS_GRADEBOOK),\n hasGoogleClassroomGradePassback: has(ASSIGNMENT_SETTINGS_PLANS.GOOGLE_CLASSROOM_GRADE_PASSBACK),\n hasAssessments: has(ASSIGNMENT_SETTINGS_PLANS.ASSESSMENTS),\n hasSectionAnalytics: has(ANALYTICS_PLANS.ANALYTICS_CLASSROOM_ANALYTICS),\n hasStudentReports: has(ANALYTICS_PLANS.ANALYTICS_STUDENT_PROGRESS_REPORTS),\n permissions: permissions || [],\n hasStudentPortfolios: permissions.hasStudentPortfolios,\n isFreeOrgTrial: permissions.type === 'free_org_trial',\n freeOrgTrialExpired: permissions.freeOrgTrialExpired,\n }\n}\n\nexport default usePermissions\n","export const SPEAKABLE_NOTIFICATIONS = {\n NEW_ASSIGNMENT: 'new_assignment',\n ASSESSMENT_SUBMITTED: 'assessment_submitted',\n ASSESSMENT_SCORED: 'assessment_scored',\n NEW_COMMENT: 'NEW_COMMENT',\n} as const\n\nexport type SpeakableNotificationType =\n (typeof SPEAKABLE_NOTIFICATIONS)[keyof typeof SPEAKABLE_NOTIFICATIONS]\n\nexport const SpeakableNotificationTypes = {\n NEW_ASSIGNMENT: 'NEW_ASSIGNMENT',\n FEEDBACK_FROM_TEACHER: 'FEEDBACK_FROM_TEACHER',\n MESSAGE_FROM_STUDENT: 'MESSAGE_FROM_STUDENT',\n PHRASE_MARKED_CORRECT: 'PHRASE_MARKED_CORRECT',\n STUDENT_PROGRESS: 'STUDENT_PROGRESS',\n PLAYLIST_FOLLOWERS: 'PLAYLIST_FOLLOWERS',\n PLAYLIST_PLAYS: 'PLAYLIST_PLAYS',\n\n // New notifications\n ASSESSMENT_SUBMITTED: 'ASSESSMENT_SUBMITTED', // Notification FOR TEACHER when student submits assessment\n ASSESSMENT_SCORED: 'ASSESSMENT_SCORED', // Notification FOR STUDENT when teacher scores assessment\n // Comment\n NEW_COMMENT: 'NEW_COMMENT',\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { type User } from '@core/types/user.types'\nimport { type AssignmentWithId } from '@core/domains/assignment'\nimport dayjs from 'dayjs'\nimport { WEB_BASE_URL } from '@core/constants/web.constants'\nimport { api } from '@core/lib/firebase/api'\n\nimport { SPEAKABLE_NOTIFICATIONS, type SpeakableNotificationType } from '../notification.constants'\n\nimport { sendNotification } from './send-notification.service'\n\nexport const createNotification = async ({\n data,\n type,\n userId,\n profile,\n}: {\n type: SpeakableNotificationType\n data: any\n userId: string\n profile: User['profile']\n}) => {\n let result\n\n switch (type) {\n case SPEAKABLE_NOTIFICATIONS.NEW_ASSIGNMENT:\n result = await handleAssignNotifPromise({ data, profile })\n break\n case SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SUBMITTED:\n result = await createAssessmentSubmissionNotification({\n data,\n profile,\n userId,\n })\n break\n case SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SCORED:\n result = await createAssessmentScoredNotification({\n data,\n profile,\n })\n break\n default:\n result = null\n break\n }\n\n return result\n}\n\nconst handleAssignNotifPromise = async ({\n data: assignments,\n profile,\n}: {\n data: any[]\n profile: User['profile']\n}) => {\n if (!assignments.length) return\n\n try {\n const notifsPromises = assignments.map(async assignment => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const {\n section,\n section: { members },\n ...rest\n } = assignment\n\n if (!section || !members) throw new Error('Invalid assignment data')\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const data = { section, sendTo: members, assignment: { ...rest } }\n\n return createNewAssignmentNotification({ data, profile })\n })\n\n await Promise.all(notifsPromises)\n\n return {\n success: true,\n message: 'Assignment notifications sent successfully',\n }\n } catch (error) {\n console.error('Error in handleAssignNotifPromise:', error)\n throw error\n }\n}\n\nconst createNewAssignmentNotification = async ({\n data,\n profile,\n}: {\n data: {\n sendTo: string[]\n assignment: AssignmentWithId\n }\n profile: User['profile']\n}) => {\n const { assignment, sendTo } = data\n\n const teacherName = profile.displayName || 'Your teacher'\n const dueDate = assignment.dueDateTimestamp\n ? dayjs(assignment.dueDateTimestamp.toDate()).format('MMM Do')\n : null\n\n const results = await sendNotification(sendTo, {\n courseId: assignment.courseId,\n type: SPEAKABLE_NOTIFICATIONS.NEW_ASSIGNMENT,\n senderName: teacherName,\n link: `${WEB_BASE_URL}/assignment/${assignment.id}`,\n messagePreview: `A new assignment \"${assignment.name}\" is now available. ${dueDate ? `Due ${dueDate}` : ''}`,\n title: 'New Assignment Available!',\n imageUrl: profile.image?.url,\n })\n\n return results\n}\n\nconst createAssessmentSubmissionNotification = async ({\n data: assignment,\n profile,\n userId,\n}: {\n data: AssignmentWithId\n profile: User['profile']\n userId: string\n}) => {\n const studentName = profile.displayName || 'Your student'\n\n const results = await sendNotification(assignment.owners, {\n courseId: assignment.courseId,\n type: SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SUBMITTED,\n link: `${WEB_BASE_URL}/a/${assignment.id}?studentId=${userId}`,\n title: `Assessment Submitted!`,\n senderName: studentName,\n messagePreview: `${studentName} has submitted the assessment \"${assignment.name}\"`,\n imageUrl: profile.image?.url,\n })\n\n return results\n}\n\nconst createAssessmentScoredNotification = async ({\n data,\n profile,\n}: {\n data: {\n assignment: AssignmentWithId\n sendTo: string[]\n }\n profile: User['profile']\n}) => {\n const { assignment, sendTo } = data\n\n const teacherName = profile.displayName || 'Your teacher'\n\n const title = `${assignment.isAssessment ? 'Assessment' : 'Assignment'} Reviewed!`\n const messagePreview = `Your ${assignment.isAssessment ? 'assessment' : 'assignment'} has been reviewed by your teacher. Click to view the feedback.`\n const results = await sendNotification(sendTo, {\n courseId: assignment.courseId,\n type: SPEAKABLE_NOTIFICATIONS.ASSESSMENT_SCORED,\n link: `${WEB_BASE_URL}/assignment/${assignment.id}`,\n title: title,\n messagePreview: messagePreview,\n imageUrl: profile.image?.url,\n senderName: teacherName,\n })\n\n await api.httpsCallable?.('sendAssessmentScoredEmail')?.({\n assessmentTitle: assignment.name,\n link: `${WEB_BASE_URL}/assignment/${assignment.id}`,\n senderImage: profile.image?.url || '',\n studentId: sendTo[0],\n teacherName: profile.displayName,\n })\n\n return results\n}\n","export const WEB_BASE_URL = 'https://app.speakable.io'\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n\nimport { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nconst _sendNotification = async (sendTo: string[], notification: any) => {\n const results = await api.httpsCallable?.('createNotificationV2')?.({\n sendTo,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n notification: notification,\n })\n\n return results\n}\n\nexport const sendNotification = withErrorHandler(_sendNotification, 'sendNotification')\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\n\nimport { createNotification } from '../services/create-notification.service'\nimport { type SpeakableNotificationType } from '../notification.constants'\n\nconst notificationQueryKeys = {\n all: ['notifications'] as const,\n byId: (id: string) => [...notificationQueryKeys.all, id] as const,\n}\n\nexport const useCreateNotification = () => {\n const { user, queryClient } = useSpeakableApi()\n\n const handleCreateNotifications = async (type: SpeakableNotificationType, data: any) => {\n const result = await createNotification({\n type,\n userId: user.auth.uid,\n profile: user?.profile ?? {},\n data,\n })\n\n queryClient.invalidateQueries({\n queryKey: notificationQueryKeys.byId(user?.auth.uid ?? ''),\n })\n\n return result\n }\n\n return {\n createNotification: handleCreateNotifications,\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { type Score } from '@core/domains/assignment'\nimport { api } from '@core/lib/firebase/api'\n\nexport const useGoogleClassroom = () => {\n const submitAssignmentToGoogleClassroom = async ({\n assignment,\n scores,\n googleUserId = null, // optional to override the user's googleUserId\n }: {\n assignment: {\n id: string\n name: string\n owners: string[]\n courseId: string\n courseWorkId: string\n isAssessment: boolean\n maxPoints: number\n }\n scores: Score\n googleUserId?: string | null\n }) => {\n try {\n const { googleClassroomUserId = null } = scores\n const googleId = googleUserId || googleClassroomUserId\n\n if (!googleId)\n return {\n error: true,\n message: 'No Google Classroom ID found',\n }\n const { courseWorkId, maxPoints, owners, courseId } = assignment\n const draftGrade = scores?.score ? (scores?.score / 100) * maxPoints : 0\n const result = await api.httpsCallable?.('submitAssignmentToGoogleClassroomV2')?.({\n teacherId: owners[0],\n courseId,\n courseWorkId,\n userId: googleId,\n draftGrade,\n })\n\n return result\n } catch (error) {\n return { error: true, message: error.message }\n }\n }\n\n return {\n submitAssignmentToGoogleClassroom,\n }\n}\n","import { type GradingStandard } from '@core/services/add-grading-standard'\n\nimport { api } from '../api'\n\nexport const logGradingStandardLog = (data: {\n type: GradingStandard['type']\n level?: GradingStandard['level']\n courseId?: GradingStandard['courseId']\n}) => {\n if (data.courseId && data.type && data.level) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: data.type || 'custom',\n level: data.level,\n courseId: data.courseId,\n })\n }\n api.logEvent('logGradingStandard', data)\n}\n","// Event constants\nexport const ANALYTICS_EVENT_TYPES = {\n VOICE_SUCCESS: 'voice_success',\n VOICE_FAIL: 'voice_fail',\n RESPOND_CARD_SUCCESS: 'respond_card_success',\n RESPOND_CARD_FAIL: 'respond_card_fail',\n RESPOND_WRITE_CARD_SUCCESS: 'respond_write_card_success',\n RESPOND_WRITE_CARD_FAIL: 'respond_write_card_fail',\n RESPOND_WRITE_CARD_SUBMITTED: 'respond_write_card_submitted',\n RESPOND_WRITE_CARD_ERROR: 'respond_write_card_error',\n RESPOND_CARD_ERROR: 'respond_card_error',\n RESPOND_CARD_SUBMITTED: 'respond_card_submitted',\n RESPOND_FREE_PLAN: 'respond_free_plan',\n RESPOND_WRITE_FREE_PLAN: 'respond_write_free_plan',\n SUBMISSION: 'assignment_submitted',\n ASSIGNMENT_STARTED: 'assignment_started',\n CREATE_ASSIGNMENT: 'create_assignment',\n MC_SUCCESS: 'multiple_choice_success',\n MC_FAIL: 'multiple_choice_fail',\n MC_ERROR: 'multiple_choice_error',\n ACTFL_LEVEL: 'actfl_level',\n WIDA_LEVEL: 'wida_level',\n // New events\n VIEW_SCORES_MODAL: 'view_scores_modal',\n SHORT_ANSWER_SUCCESS: 'short_answer_success',\n SHORT_ANSWER_FAIL: 'short_answer_fail',\n SHORT_ANSWER_ERROR: 'short_answer_error',\n RETRY: 'retry',\n MESSAGE_SENT: 'message_sent',\n MESSAGE_ERROR: 'message_error',\n VIEW_DETAILS_CLICK: 'view_details_click',\n TABS_CLICK: 'tabs_click',\n VIEW_MEDIA: 'view_media',\n VIEW_SCORES: 'view_scores',\n VIEW_GRADING_METHOD: 'view_grading_method',\n VIEW_FEEDBACK: 'view_feedback',\n} as const\n","import { ANALYTICS_EVENT_TYPES } from '@core/constants/analytics.constants'\n\nimport { api } from '../api'\n\nexport const logOpenAssignment = (data = {}) => {\n api.logEvent('open_assignment', data)\n}\n\nexport const logOpenActivityPreview = (data = {}) => {\n api.logEvent('open_activity_preview', data)\n}\n\nexport const logSubmitAssignment = (data = {}) => {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.SUBMISSION,\n ...data,\n })\n api.logEvent(ANALYTICS_EVENT_TYPES.SUBMISSION, data)\n}\n\nexport const logCreateAssignment = (data = {}) => {\n // @ts-ignore\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT,\n ...data,\n })\n }\n api.logEvent(ANALYTICS_EVENT_TYPES.CREATE_ASSIGNMENT, data)\n}\n\nexport const logStartAssignment = (data = {}) => {\n // @ts-ignore\n if (data.courseId) {\n api.httpsCallable?.('handleCouresAnalyticsEvent')?.({\n eventType: ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED,\n ...data,\n })\n }\n api.logEvent(ANALYTICS_EVENT_TYPES.ASSIGNMENT_STARTED, data)\n}\n\nexport const logViewScoresModal = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_SCORES_MODAL, data)\n}\n\nexport const logViewMedia = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_MEDIA, data)\n}\n\nexport const logViewScores = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_SCORES, data)\n}\n\nexport const logViewGradingMethod = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_GRADING_METHOD, data)\n}\n\nexport const logViewFeedback = (data = {}) => {\n api.logEvent(ANALYTICS_EVENT_TYPES.VIEW_FEEDBACK, data)\n}\n","import { api } from '@core/lib/firebase/api'\n\nimport { type Score } from '../assignment.model'\n\nexport const defaultScore = (props: {\n owners: string[]\n courseId?: string\n userId: string\n googleClassroomUserId?: string\n}): Score => {\n const { serverTimestamp } = api.accessHelpers()\n\n const score = {\n progress: 0,\n score: 0,\n startDate: serverTimestamp(),\n status: 'IN_PROGRESS',\n submitted: false,\n cards: {},\n lastPlayed: serverTimestamp(),\n owners: props.owners,\n userId: props.userId,\n } as Score\n\n if (props.googleClassroomUserId) {\n score.googleClassroomUserId = props.googleClassroomUserId\n }\n\n if (props.courseId) {\n score.courseId = props.courseId\n }\n\n return score\n}\n","export const SCORES_PRACTICE_COLLECTION = 'users'\n\nexport const SCORES_PRACTICE_SUBCOLLECTION = 'practice'\n\nexport const refsScoresPractice = {\n practiceScores: (params: { userId: string; setId: string }) =>\n `${SCORES_PRACTICE_COLLECTION}/${params.userId}/${SCORES_PRACTICE_SUBCOLLECTION}/${params.setId}` as const,\n practiceScoreHistoryRefDoc: (params: { userId: string; setId: string; date: string }) =>\n `${SCORES_PRACTICE_COLLECTION}/${params.userId}/${SCORES_PRACTICE_SUBCOLLECTION}/${params.setId}/attempts/${params.date}` as const,\n}\n","import { withErrorHandler } from '@core/utils/error-handler'\nimport { api } from '@core/lib/firebase/api'\n\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { type Score } from '../assignment.model'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nasync function _createScore(params: {\n isAssignment: boolean\n activityId: string\n userId: string\n scoreData: Score\n}) {\n if (params.isAssignment) {\n const ref = refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n\n await api.httpsCallable?.('updateAssignmentGradebookStatus')?.({\n assignmentId: params.activityId,\n userId: params.userId,\n status: 'IN_PROGRESS',\n score: null,\n })\n\n await api.setDoc(ref, params.scoreData, { merge: true })\n\n return {\n id: params.userId,\n }\n } else {\n const ref = refsScoresPractice.practiceScores({\n userId: params.userId,\n setId: params.activityId,\n })\n\n await api.setDoc(ref, params.scoreData)\n\n return {\n id: params.userId,\n }\n }\n}\n\nexport const createScore = withErrorHandler(_createScore, 'createScore')\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\nimport { logStartAssignment } from '@core/lib/firebase/firebase-analytics'\n\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { type Score, type ScoreWithId } from '../assignment.model'\nimport { defaultScore } from '../utils/create-default-score'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nimport { createScore } from './create-score.service'\n\nexport async function getAssignmentScore({\n userId,\n assignment,\n googleClassroomUserId,\n}: {\n userId: string\n assignment: {\n id: string\n courseId?: string\n }\n googleClassroomUserId?: string\n}) {\n const path = refsAssignmentFiresotre.assignmentScores({\n id: assignment.id,\n userId,\n })\n\n const response = await api.getDoc<ScoreWithId>(path)\n\n if (response.data == null) {\n const newScore: Score = {\n ...defaultScore({\n owners: [userId],\n userId,\n courseId: assignment.courseId,\n googleClassroomUserId,\n }),\n assignmentId: assignment.id,\n }\n\n logStartAssignment({\n courseId: assignment.courseId,\n })\n\n const result = await createScore({\n activityId: assignment.id,\n userId,\n isAssignment: true,\n scoreData: newScore,\n })\n\n return {\n ...newScore,\n id: result.id,\n }\n }\n\n return response.data\n}\n\nexport async function getPracticeScore({ userId, setId }: { userId: string; setId: string }) {\n const path = refsScoresPractice.practiceScores({ userId, setId })\n\n const response = await api.getDoc<ScoreWithId>(path)\n\n if (response.data == null) {\n const newScore: Score = {\n ...defaultScore({\n owners: [userId],\n userId,\n }),\n setId,\n }\n\n const result = await createScore({\n activityId: setId,\n userId,\n isAssignment: false,\n scoreData: newScore,\n })\n\n return {\n ...newScore,\n id: result.id,\n }\n }\n\n return response.data\n}\n\nasync function _getScore(params: {\n userId: string\n activityId: string\n courseId?: string\n googleClassroomUserId?: string\n isAssignment: boolean\n}) {\n if (params.isAssignment) {\n return await getAssignmentScore({\n userId: params.userId,\n assignment: {\n id: params.activityId,\n courseId: params.courseId,\n },\n googleClassroomUserId: params.googleClassroomUserId,\n })\n } else {\n return await getPracticeScore({\n userId: params.userId,\n setId: params.activityId,\n })\n }\n}\n\nexport const getScore = withErrorHandler(_getScore, 'getScore')\n","import { type Score, type PageScore } from '../assignment.model'\n\nconst calculateScoreAndProgress = (\n scores: Score,\n cardsList: string[],\n weights: Record<string, number>,\n) => {\n const filteredScoreCards = Object.keys(scores?.cards || {}).reduce<Record<string, PageScore>>(\n (acc, cardId) => {\n const cardScores = scores?.cards?.[cardId]\n\n if (cardScores && !cardScores.media_area_opened) {\n acc[cardId] = cardScores\n }\n\n return acc\n },\n {},\n )\n\n const totalSetPoints = cardsList.reduce((acc, cardId) => {\n acc += weights?.[cardId] || 1\n\n return acc\n }, 0)\n\n const totalPointsAwarded = Object.keys(filteredScoreCards).reduce((acc, cardId) => {\n const cardScores = filteredScoreCards[cardId]\n\n if (cardScores?.completed || cardScores?.score || cardScores?.score === 0) {\n const score =\n cardScores?.score || cardScores?.score === 0 ? Number(cardScores?.score ?? 0) : null\n const weight = weights?.[cardId] || 1\n const fraction = (score ?? 0) / 100\n\n if (score || score === 0) {\n acc += weight * fraction\n } else {\n acc += weight\n }\n }\n\n return acc\n }, 0)\n\n const totalCompletedCards = Object.keys(filteredScoreCards).reduce((acc, cardId) => {\n const cardScores = filteredScoreCards[cardId]\n\n if (cardScores?.completed || cardScores?.score || cardScores?.score === 0) {\n acc += 1\n }\n\n return acc\n }, 0)\n\n const percent = totalPointsAwarded / totalSetPoints\n\n const score = Math.round(percent * 100)\n\n const progress = Math.round((totalCompletedCards / (cardsList.length || 1)) * 100)\n\n return { score, progress }\n}\n\nexport default calculateScoreAndProgress\n","// export async function updateScore(props: UpdateScore) {\n// const { userId, data, type } = props\n\nimport { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { type Score, type PageScore } from '../assignment.model'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nasync function _updateScore(params: {\n userId: string\n data: Partial<Score>\n isAssignment: boolean\n activityId: string\n}) {\n const path = params.isAssignment\n ? refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n : refsScoresPractice.practiceScores({\n setId: params.activityId,\n userId: params.userId,\n })\n\n await api.updateDoc(path, {\n ...params.data,\n })\n}\n\nexport const updateScore = withErrorHandler(_updateScore, 'updateScore')\n\nasync function _updateCardScore(params: {\n userId: string\n cardId: string\n isAssignment: boolean\n activityId: string\n updates: {\n cardScore: PageScore\n progress: number\n score: number\n }\n}) {\n const path = params.isAssignment\n ? refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n : refsScoresPractice.practiceScores({\n setId: params.activityId,\n userId: params.userId,\n })\n\n const updates = Object.keys(params.updates.cardScore).reduce<Record<string, unknown>>(\n (acc, key) => {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n acc[`cards.${params.cardId}.${key}`] = params.updates.cardScore[key]\n\n return acc\n },\n {},\n )\n\n if (params.updates.progress) {\n updates.progress = params.updates.progress\n }\n if (params.updates.score) {\n updates.score = params.updates.score\n }\n\n await api.updateDoc(path, {\n ...updates,\n })\n}\n\nexport const updateCardScore = withErrorHandler(_updateCardScore, 'updateCardScore')\n","import dayjs from 'dayjs'\nimport { api } from '@core/lib/firebase/api'\n\nimport { type PageScore, type Score } from '../assignment.model'\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nexport async function clearScore(params: {\n isAssignment: boolean\n cardId: string\n cardScores: PageScore\n userId: string\n activityId: string\n}) {\n const update: Partial<Score> = {\n [`cards.${params.cardId}`]: {\n attempts: (params.cardScores.attempts ?? 1) + 1,\n correct: params.cardScores.correct ?? 0,\n // save old score history\n history: [\n {\n ...params.cardScores,\n attempts: params.cardScores.attempts ?? 1,\n correct: params.cardScores.correct ?? 0,\n retryTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),\n history: null,\n },\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n ...(params.cardScores.history ?? []),\n ],\n },\n }\n\n const path = params.isAssignment\n ? refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n : refsScoresPractice.practiceScores({\n setId: params.activityId,\n userId: params.userId,\n })\n\n await api.updateDoc(path, update)\n\n return {\n update,\n activityId: params.activityId,\n }\n}\n\nexport async function clearScoreV2(params: {\n isAssignment: boolean\n cardId: string\n cardScores: PageScore\n userId: string\n activityId: string\n}) {\n const update: Partial<Score> = {\n [`cards.${params.cardId}`]: {\n ...params.cardScores,\n attempts: (params.cardScores.attempts ?? 1) + 1,\n correct: params.cardScores.correct ?? 0,\n history: [\n {\n ...params.cardScores,\n attempts: params.cardScores.attempts ?? 1,\n correct: params.cardScores.correct ?? 0,\n retryTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),\n history: null,\n },\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n ...(params.cardScores.history ?? []),\n ],\n },\n }\n\n const path = params.isAssignment\n ? refsAssignmentFiresotre.assignmentScores({\n id: params.activityId,\n userId: params.userId,\n })\n : refsScoresPractice.practiceScores({\n setId: params.activityId,\n userId: params.userId,\n })\n\n await api.updateDoc(path, update)\n\n return {\n update,\n activityId: params.activityId,\n }\n}\n","import { api } from '@core/lib/firebase/api'\nimport dayjs from 'dayjs'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { type Score } from '../assignment.model'\nimport { refsAssignmentFiresotre } from '../assignment.constants'\nimport calculateScoreAndProgress from '../utils/calculateScoreAndProgress'\nimport { refsScoresPractice } from '../score-practice.constants'\n\nasync function _submitAssignmentScore({\n cardIds,\n assignment,\n weights,\n userId,\n status,\n studentName,\n}: {\n cardIds: string[]\n assignment: {\n id: string\n name: string\n owners: string[]\n courseId: string\n courseWorkId: string\n isAssessment: boolean\n }\n weights: Record<string, number>\n userId: string\n status: Score['status']\n studentName: string\n}) {\n const { serverTimestamp } = api.accessHelpers()\n\n const path = refsAssignmentFiresotre.assignmentScores({ id: assignment.id, userId })\n\n const fieldsUpdated = {\n submitted: true,\n progress: 100,\n submissionDate: serverTimestamp(),\n status,\n } as Score\n\n if (assignment.isAssessment) {\n const result = await handleAssessment(\n assignment,\n userId,\n cardIds,\n weights,\n fieldsUpdated,\n studentName,\n )\n\n return result\n } else if (assignment.courseId) {\n await handleCourseAssignment(assignment, userId)\n }\n\n await api.updateDoc(path, { ...fieldsUpdated })\n\n return { success: true, fieldsUpdated }\n}\n\nexport const submitAssignmentScore = withErrorHandler(\n _submitAssignmentScore,\n 'submitAssignmentScore',\n)\n\nasync function handleAssessment(\n assignment: { id: string; name: string; owners: string[] },\n userId: string,\n cardIds: string[],\n weights: Record<string, number>,\n fieldsUpdated: Score,\n studentName: string,\n) {\n const path = refsAssignmentFiresotre.assignmentScores({ id: assignment.id, userId })\n\n const response = await api.getDoc<Score>(path)\n\n if (!response.data) {\n throw new Error('Score not found')\n }\n\n const { score: scoreCalculated } = calculateScoreAndProgress(response.data, cardIds, weights)\n\n await api.updateDoc(path, { score: scoreCalculated, status: 'PENDING_REVIEW' })\n\n await api.httpsCallable?.('submitAssessment')?.({\n assignmentId: assignment.id,\n assignmentTitle: assignment.name,\n userId,\n teacherId: assignment.owners[0],\n studentName,\n })\n\n fieldsUpdated.status = 'PENDING_REVIEW'\n\n return { success: true, fieldsUpdated }\n}\n\nasync function handleCourseAssignment(assignment: { id: string }, userId: string) {\n await api.httpsCallable?.('submitAssignmentV2')?.({\n assignmentId: assignment.id,\n userId,\n })\n}\n\nexport async function submitPracticeScore({\n setId,\n userId,\n scores,\n}: {\n userId: string\n setId: string\n scores: Score\n}) {\n const { serverTimestamp } = api.accessHelpers()\n\n // Create new scores object on the practice set subcollection /attempts\n const date = dayjs().format('YYYY-MM-DD-HH-mm')\n\n const ref = refsScoresPractice.practiceScoreHistoryRefDoc({ setId, userId, date })\n\n const fieldsUpdated = {\n ...scores,\n submitted: true,\n progress: 100,\n submissionDate: serverTimestamp(),\n status: 'SUBMITTED',\n } as Score\n\n await api.setDoc(ref, { ...fieldsUpdated })\n\n // clear the existing scores doc\n const refScores = refsScoresPractice.practiceScores({ userId, setId })\n\n await api.deleteDoc(refScores)\n\n return { success: true, fieldsUpdated }\n}\n","import { type QueryClient, useMutation, useQueries, useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\n\nimport { getCard } from './services/get-card.service'\nimport { type PageActivityWithId } from './card.model'\nimport { createCard, createCards } from './services/create-card.service'\n\nexport const cardsQueryKeys = {\n all: ['cards'],\n one: (params: { cardId: string }) => [...cardsQueryKeys.all, params.cardId],\n}\n\nexport function useCards({\n cardIds,\n enabled = true,\n asObject,\n}: {\n cardIds: string[]\n enabled: boolean\n asObject?: boolean\n}) {\n const queries = useQueries({\n queries: cardIds.map(cardId => ({\n enabled: enabled && cardIds.length > 0,\n queryKey: cardsQueryKeys.one({\n cardId,\n }),\n queryFn: () => getCard({ cardId }),\n })),\n })\n\n const cards = queries.map(query => query.data).filter(Boolean) as unknown as PageActivityWithId[]\n\n const cardsObject = useMemo(() => {\n if (!asObject) return null\n\n return cards.reduce<Record<string, PageActivityWithId>>((acc, card) => {\n acc[card.id] = card\n\n return acc\n }, {})\n }, [asObject, cards])\n\n return {\n cards,\n cardsObject,\n cardsQueries: queries,\n }\n}\n\nexport function useCreateCard() {\n const { queryClient } = useSpeakableApi()\n\n const mutationCreateCard = useMutation({\n mutationFn: createCard,\n onSuccess: cardCreated => {\n queryClient.invalidateQueries({ queryKey: cardsQueryKeys.one({ cardId: cardCreated.id }) })\n },\n })\n\n return {\n mutationCreateCard,\n }\n}\n\nexport function useCreateCards() {\n const mutationCreateCards = useMutation({\n mutationFn: createCards,\n })\n\n return {\n mutationCreateCards,\n }\n}\n\nexport function getCardFromCache({\n cardId,\n queryClient,\n}: {\n cardId: string\n queryClient: QueryClient\n}) {\n return queryClient.getQueryData<PageActivityWithId>(cardsQueryKeys.one({ cardId }))\n}\n\nexport function updateCardInCache({\n cardId,\n card,\n queryClient,\n}: {\n cardId: string\n card: PageActivityWithId | null\n queryClient: QueryClient\n}): void {\n queryClient.setQueryData(cardsQueryKeys.one({ cardId }), card)\n}\n\nexport function useGetCard({ cardId, enabled = true }: { cardId: string; enabled?: boolean }) {\n const query = useQuery({\n queryKey: cardsQueryKeys.one({ cardId }),\n queryFn: () => getCard({ cardId }),\n enabled: enabled && !!cardId,\n })\n\n return query\n}\n","import { type VerificationCardStatus } from './card.constants'\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport interface PageActivityWithId extends PageActivity {\n id: string\n}\n\nexport interface PageActivity {\n owners: string[]\n checked?: boolean\n completed?: boolean\n media_area_id?: string | null\n media_area_layout?: 'left' | 'right' | null\n media_mode?: 'single' | 'media_area' | 'none' | null\n media?: {\n type: 'image' | 'video'\n url: string\n } | null\n score?: number\n verificationStatus?: VerificationCardStatus\n native_text?: string\n repeat?: number\n language?: string | null\n image?: {\n path?: string | null\n url?: string\n }\n audio?: {\n path?: string | null\n url?: string\n } | null\n notes?: string\n difficulty?: string\n default_language?: string\n target_text?: string\n type: ActivityPageType\n grading_criteria?: string\n scoring_type?: string\n grading_method?: 'simple' | 'rubric' | 'manual' | 'standards_based'\n feedback_types?: string[]\n rubricId?: string\n prompt?: string\n title?: string\n passing_score?: number\n maxCharacters?: number\n answer?: string[]\n choices?: {\n value: string\n option: string\n }[]\n MCQType?: string\n multipleAttemptsAllowed?: boolean\n allowRetries?: boolean\n question?: string\n respondTime?: number\n hidePrompt?: boolean\n videoUrl?: string\n link?: string\n text?: string\n isListenAloud?: boolean\n embedCode?: string\n attempt?: number\n correct?: number\n autoGrade?: boolean\n points?: number\n shuffle?: boolean\n translation?: string\n includeAIContext?: boolean\n media_area_context_ref?: string | null\n standardId?: string\n target_proficiency_level?: string\n allowTTS?: boolean\n feedback_language?: string | null\n correct_answer?: string | null\n limit_attempts?: boolean\n max_attempts?: number\n rich_text?: string\n}\n\nexport const enum ActivityPageType {\n // DEFAULT = 'READ_REPEAT',\n READ_REPEAT = 'READ_REPEAT',\n READ_RESPOND = 'READ_RESPOND',\n FREE_RESPONSE = 'FREE_RESPONSE',\n REPEAT = 'REPEAT',\n RESPOND = 'RESPOND',\n RESPOND_WRITE = 'RESPOND_WRITE',\n MULTIPLE_CHOICE = 'MULTIPLE_CHOICE',\n MEDIA_PAGE = 'MEDIA_PAGE',\n SHORT_ANSWER = 'SHORT_ANSWER',\n}\n\nexport const RESPOND_PAGE_ACTIVITY_TYPES = [\n ActivityPageType.READ_RESPOND,\n ActivityPageType.RESPOND,\n ActivityPageType.RESPOND_WRITE,\n ActivityPageType.FREE_RESPONSE,\n]\n\nexport const MULTIPLE_CHOICE_PAGE_ACTIVITY_TYPES = [ActivityPageType.MULTIPLE_CHOICE]\n\nexport const REPEAT_PAGE_ACTIVITY_TYPES = [ActivityPageType.READ_REPEAT, ActivityPageType.REPEAT]\n\nexport const RESPOND_WRITE_PAGE_ACTIVITY_TYPES = [\n ActivityPageType.RESPOND_WRITE,\n ActivityPageType.FREE_RESPONSE,\n]\n\nexport const RESPOND_AUDIO_PAGE_ACTIVITY_TYPES = [\n ActivityPageType.RESPOND,\n ActivityPageType.READ_RESPOND,\n]\n","/* eslint-disable @typescript-eslint/naming-convention */\n\nexport enum FeedbackTypesCard {\n SuggestedResponse = 'suggested_response',\n Wida = 'wida',\n GrammarInsights = 'grammar_insights',\n Actfl = 'actfl',\n ProficiencyLevel = 'proficiency_level',\n}\n\nexport enum LeniencyCard {\n CONFIDENCE = 'confidence',\n EASY = 'easy',\n NORMAL = 'normal',\n HARD = 'hard',\n}\n\nexport const LENIENCY_OPTIONS = [\n {\n label: 'Build Confidence - most lenient',\n value: LeniencyCard.CONFIDENCE,\n },\n {\n label: 'Very Lenient',\n value: LeniencyCard.EASY,\n },\n {\n label: 'Normal',\n value: LeniencyCard.NORMAL,\n },\n {\n label: 'No leniency - most strict',\n value: LeniencyCard.HARD,\n },\n]\n\nexport const STUDENT_LEVELS_OPTIONS = [\n {\n label: 'Beginner',\n description: 'Beginner Level: Just starting out. Can say a few basic words and phrases.',\n value: 'beginner',\n },\n {\n label: 'Elementary',\n description:\n 'Elementary Level: Can understand simple sentences and have very basic conversations.',\n value: 'elementary',\n },\n {\n label: 'Intermediate',\n description: 'Intermediate Level: Can talk about everyday topics and handle common situations.',\n value: 'intermediate',\n },\n {\n label: 'Advanced',\n description: 'Advanced Level: Can speak and understand with ease, and explain ideas clearly.',\n value: 'advanced',\n },\n {\n label: 'Fluent',\n description:\n 'Fluent Level: Speaks naturally and easily. Can use the language in work or school settings.',\n value: 'fluent',\n },\n {\n label: 'Native-like',\n description:\n 'Native-like Level: Understands and speaks like a native. Can discuss complex ideas accurately.',\n value: 'nativeLike',\n },\n]\n\nexport const BASE_RESPOND_FIELD_VALUES = {\n title: '',\n allowRetries: true,\n respondTime: 180,\n maxCharacters: 1000,\n}\n\nexport const BASE_REPEAT_FIELD_VALUES = {\n repeat: 1,\n}\n\nexport const BASE_MULTIPLE_CHOICE_FIELD_VALUES = {\n MCQType: 'single',\n answer: ['A'],\n choices: [\n { option: 'A', value: 'Option A' },\n { option: 'B', value: 'Option B' },\n { option: 'C', value: 'Option C' },\n ],\n}\n\nexport enum VerificationCardStatus {\n VERIFIED = 'VERIFIED',\n WARNING = 'WARNING',\n NOT_RECOMMENDED = 'NOT_RECOMMENDED',\n NOT_WORKING = 'NOT_WORKING',\n NOT_CHECKED = 'NOT_CHECKED',\n}\n\nconst CARDS_COLLECTION = 'flashcards'\n\nexport type RefsCardsFiresotre = `${typeof CARDS_COLLECTION}/${string}`\n\nexport const refsCardsFiresotre = {\n allCards: CARDS_COLLECTION,\n card: (id: string) => `${CARDS_COLLECTION}/${id}` as const,\n}\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { ActivityPageType, type PageActivityWithId } from '../card.model'\nimport { refsCardsFiresotre } from '../card.constants'\n\nasync function _getCard(params: { cardId: string }) {\n const ref = refsCardsFiresotre.card(params.cardId)\n\n const response = await api.getDoc<PageActivityWithId>(ref)\n\n if (!response.data) return null\n\n const type = response.data.type || ActivityPageType.READ_REPEAT\n\n const cardsMapped = {\n ...response.data,\n type: type,\n }\n\n return cardsMapped\n}\n\nexport const getCard = withErrorHandler(_getCard, 'getCard')\n","import { v4 } from 'uuid'\nimport { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { ActivityPageType, type PageActivityWithId, type PageActivity } from '../card.model'\nimport { refsCardsFiresotre } from '../card.constants'\n\nimport { getVerificationStatus } from './get-card-verification-status.service'\n\nasync function _createCard({ data }: { data: Partial<PageActivity> }) {\n const response = await api.addDoc(refsCardsFiresotre.allCards, data)\n\n return response\n}\n\nexport const createCard = withErrorHandler(_createCard, 'createCard')\n\nasync function _createCards({ cards }: { cards: PageActivity[] }) {\n const { writeBatch, doc } = api.accessHelpers()\n\n const batch = writeBatch()\n\n const cardsWithId = []\n\n for (const card of cards) {\n const cardId = v4()\n\n const ref = doc(refsCardsFiresotre.card(cardId))\n\n const newCardObject = {\n ...card,\n id: cardId,\n }\n\n if (card.type === ActivityPageType.READ_REPEAT && card.target_text && card.language) {\n const verificationStatus = await getVerificationStatus(card.target_text, card.language)\n\n newCardObject.verificationStatus = verificationStatus || null\n }\n cardsWithId.push(newCardObject)\n batch.set(ref, newCardObject)\n }\n\n await batch.commit()\n\n return cardsWithId satisfies PageActivityWithId[]\n}\n\nexport const createCards = withErrorHandler(_createCards, 'createCards')\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\nimport { sha1 } from 'js-sha1'\n\nexport const purify = (word: string) => {\n return word\n .normalize('NFD')\n .replace(/\\/([^\" \"]*)/g, '') // removes word after slash to space el/la --> el\n .replace(/\\([^()]*\\)/g, '') // removes word parenthesis\n .replace(/([^()]*)/g, '') //removes chinese parenthesis\n .replace(/[\\u0300-\\u036f]/g, '') // removes diacritics\n .replace(/[-]/g, ' ') // removes hyphens\n .replace(/[.,/#!¡¿?؟。,.?$%^&*;:{}=\\-_`~()’'…\\s]/g, '') // removes punctuation\n .replace(/\\s\\s+/g, ' ') //Removes all whitespace\n .toLowerCase()\n .trim()\n}\n\nexport const cleanString = (words: string) => {\n const splitWords = words?.split('+')\n\n if (splitWords && splitWords.length === 1) {\n const newWord = purify(words)\n\n return newWord\n } else if (splitWords && splitWords.length > 1) {\n const split = splitWords.map(w => purify(w))\n\n return split\n } else {\n return ''\n }\n}\n\nexport const getWordHash = (word: string, language: string) => {\n const cleanedWord = cleanString(word)\n const wordHash = sha1(`${language}-${cleanedWord as string}`)\n\n console.log('wordHash core library', wordHash)\n\n return wordHash\n}\n\nexport function getPhraseLength(phrase: string, input?: string) {\n if (Array.isArray(phrase) && phrase.includes(input)) {\n return phrase[phrase.indexOf(input)].split(' ').length as number\n } else {\n return phrase ? phrase.split(' ').length : (0 as number)\n }\n}\n","/* eslint-disable @typescript-eslint/restrict-plus-operands */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { getWordHash } from '@core/utils/text-utils'\nimport { api } from '@core/lib/firebase/api'\n\nimport { VerificationCardStatus } from '../card.constants'\n\nconst charactarLanguages = ['zh', 'ja', 'ko']\n\nexport const getVerificationStatus = async (target_text: string, language: string) => {\n if (target_text?.length < 3 && !charactarLanguages.includes(language)) {\n return VerificationCardStatus.NOT_RECOMMENDED\n }\n const hash = getWordHash(target_text, language)\n const response = await api.getDoc<any>(`checked-pronunciations/${hash}`)\n\n try {\n if (response.data) {\n return processRecord(response.data)\n } else {\n return VerificationCardStatus.NOT_CHECKED\n }\n } catch (e) {\n return VerificationCardStatus.NOT_CHECKED\n }\n}\n\nconst processRecord = (data: any) => {\n const { pronunciations = 0, fails = 0 } = data\n const attempts = pronunciations + fails\n const successRate = attempts > 0 ? (pronunciations / attempts) * 100 : 0\n let newStatus = null\n\n if (attempts < 6) {\n return VerificationCardStatus.NOT_CHECKED\n }\n if (successRate > 25) {\n // console.log('Verified')\n newStatus = VerificationCardStatus.VERIFIED\n } else if (successRate > 10) {\n // console.log('Warning')\n newStatus = VerificationCardStatus.WARNING\n } else if (fails > 20 && successRate < 10 && pronunciations > 1) {\n // console.log('Not recommended for use')\n newStatus = VerificationCardStatus.NOT_RECOMMENDED\n } else if (pronunciations === 0 && fails > 20) {\n // console.log('does not work')\n newStatus = VerificationCardStatus.NOT_WORKING\n } else {\n // console.log('no data - must be checked')\n newStatus = VerificationCardStatus.NOT_CHECKED\n }\n\n return newStatus\n}\n","import { createCards } from './services/create-card.service'\nimport { createCard } from './services/create-card.service'\nimport { getCard } from './services/get-card.service'\n\nexport const createCardRepo = () => {\n return {\n createCard: createCard,\n createCards: createCards,\n getCard: getCard,\n }\n}\n","import {\n ActivityPageType,\n REPEAT_PAGE_ACTIVITY_TYPES,\n MULTIPLE_CHOICE_PAGE_ACTIVITY_TYPES,\n RESPOND_PAGE_ACTIVITY_TYPES,\n RESPOND_WRITE_PAGE_ACTIVITY_TYPES,\n RESPOND_AUDIO_PAGE_ACTIVITY_TYPES,\n} from '../card.model'\n\nexport function checkIsRepeatPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return REPEAT_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport function checkIsMCPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return MULTIPLE_CHOICE_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport function checkIsRespondPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return RESPOND_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport function checkIsRespondWrittenPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return RESPOND_WRITE_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport function checkIsRespondAudioPage(cardType: ActivityPageType | undefined) {\n if (cardType === undefined) return false\n\n return RESPOND_AUDIO_PAGE_ACTIVITY_TYPES.includes(cardType)\n}\n\nexport const checkIsMediaPage = (cardType: ActivityPageType | undefined) => {\n if (cardType === undefined) return false\n\n return cardType === ActivityPageType.MEDIA_PAGE\n}\n\nexport const checkIsShortAnswerPage = (cardType: ActivityPageType | undefined) => {\n if (cardType === undefined) return false\n\n return cardType === ActivityPageType.SHORT_ANSWER\n}\n\nexport const checkTypePageActivity = (cardType: ActivityPageType | undefined) => {\n const isRespondAudio = checkIsRespondAudioPage(cardType)\n const isRespondWritten = checkIsRespondWrittenPage(cardType)\n\n const isRespond = checkIsRespondPage(cardType)\n const isMC = checkIsMCPage(cardType)\n const isRepeat = checkIsRepeatPage(cardType)\n const isMediaPage = checkIsMediaPage(cardType)\n\n const isShortAnswer = checkIsShortAnswerPage(cardType)\n\n const isNoOneOfThem = !isRespond && !isMC && !isRepeat && !isMediaPage && !isShortAnswer\n\n if (isNoOneOfThem) {\n return {\n isRespondAudio: false,\n isRespondWritten: false,\n isRespond: false,\n isMC: false,\n isRepeat: true,\n isMediaPage: false,\n isShortAnswer: false,\n hasSomeType: false,\n }\n }\n\n return {\n isRespondAudio,\n isRespondWritten,\n isRespond,\n isMC,\n isRepeat,\n isMediaPage,\n isShortAnswer,\n hasSomeType: true,\n }\n}\n","import { type PageActivityWithId } from '../card.model'\n\nimport { checkTypePageActivity } from './check-page-type'\n\nfunction extractTextFromRichText(richText: string | undefined): string {\n if (!richText) return ''\n\n return richText\n .replace(/<[^>]*>/g, '')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .trim()\n}\n\nexport function getPagePrompt(card: PageActivityWithId | undefined) {\n if (!card) return { has: false, text: '', rich_text: '', isTextEqualToRichText: false }\n\n const { isMC, isRepeat, isRespond, isShortAnswer } = checkTypePageActivity(card?.type)\n const hidePrompt = card?.hidePrompt === true\n\n const createReturnObject = (text: string | undefined, richText: string | undefined) => {\n const plainText = text || ''\n const richTextPlain = extractTextFromRichText(richText)\n\n return {\n has: true,\n text: plainText,\n rich_text: richText || '',\n isTextEqualToRichText: plainText.trim() === richTextPlain.trim(),\n }\n }\n\n if (isRepeat) {\n return createReturnObject(card?.target_text, card?.rich_text)\n }\n\n if (isRespond && !hidePrompt) {\n return createReturnObject(card?.prompt, card?.rich_text)\n }\n\n if (isMC) {\n return createReturnObject(card?.question, card?.rich_text)\n }\n\n if (isShortAnswer && !hidePrompt) {\n return createReturnObject(card?.prompt, card?.rich_text)\n }\n\n return {\n has: false,\n text: '',\n rich_text: '',\n isTextEqualToRichText: false,\n }\n}\n","import { type Score } from '@core/domains/assignment'\n\nexport const getTotalCompletedCards = (pageScores: Score['cards'] | undefined) => {\n return Object.values(pageScores ?? {}).reduce((acc, cardScore) => {\n if (\n (cardScore.completed ?? cardScore.score ?? cardScore.score === 0) &&\n !cardScore.media_area_opened\n ) {\n acc++\n }\n\n return acc\n }, 0)\n}\n","import { type ActivityPageType } from '../card.model'\n\nimport { checkTypePageActivity } from './check-page-type'\n\nconst labels = {\n repeat: {\n short: 'Repeat',\n long: 'Listen & Repeat',\n },\n mc: {\n short: 'Multiple Choice',\n long: 'Multiple Choice',\n },\n mediaPage: {\n short: 'Media Page',\n long: 'Media Page',\n },\n shortAnswer: {\n short: 'Short Answer',\n long: 'Short Answer',\n },\n respondWritten: {\n short: 'Open Response',\n long: 'Written Open Response',\n },\n respondAudio: {\n short: 'Open Response',\n long: 'Spoken Open Response',\n },\n}\n\nexport const getLabelPage = (pageType: ActivityPageType | undefined) => {\n if (!pageType) {\n return {\n short: '',\n long: '',\n }\n }\n\n const { isRepeat, isMC, isMediaPage, isShortAnswer, isRespondWritten, isRespondAudio } =\n checkTypePageActivity(pageType)\n\n if (isRepeat) {\n return labels.repeat\n }\n\n if (isMC) {\n return labels.mc\n }\n\n if (isMediaPage) {\n return labels.mediaPage\n }\n\n if (isShortAnswer) {\n return labels.shortAnswer\n }\n\n if (isRespondWritten) {\n return labels.respondWritten\n }\n\n if (isRespondAudio) {\n return labels.respondAudio\n }\n\n return {\n short: '',\n long: '',\n }\n}\n","import { type PageActivityWithId } from '../card.model'\n\nimport { checkTypePageActivity } from './check-page-type'\n\nexport function getPageMediaData(page: PageActivityWithId) {\n const direction = page.media_area_layout ?? 'left'\n const { isMediaPage } = checkTypePageActivity(page.type)\n const mode = page.media_mode ?? (page.media_area_id ? 'media_area' : null)\n const singleMedia = getSingleMediaPageData(page)\n\n const hasMediaData = isMediaPage || singleMedia !== undefined\n\n return {\n direction,\n mode,\n singleMedia,\n isMediaPage,\n hasMediaData,\n }\n}\n\nexport function getSingleMediaPageData(page: PageActivityWithId) {\n const isSingleMode = page.media_mode === 'single'\n\n if (!isSingleMode || !page.media) return undefined\n\n const media = {\n type: page.media.type,\n content: page.media.url,\n }\n\n return {\n ...media,\n rawObject: page.media,\n }\n}\n","import { type QueryClient, useQuery } from '@tanstack/react-query'\n\nimport { getSet } from './services/get-set.service'\nimport { type SetWithId } from './set.model'\n\nexport const setsQueryKeys = {\n all: ['sets'],\n one: (params: { setId: string }) => [...setsQueryKeys.all, params.setId],\n}\n\nexport const useSet = ({ setId, enabled }: { setId: string; enabled?: boolean }) => {\n return useQuery({\n queryKey: setsQueryKeys.one({ setId }),\n queryFn: () => getSet({ setId }),\n enabled: setId !== undefined && setId !== '' && enabled,\n })\n}\n\nexport function getSetFromCache({\n setId,\n queryClient,\n}: {\n setId: string | undefined\n queryClient: QueryClient\n}) {\n if (!setId) return null\n\n return queryClient.getQueryData<SetWithId>(setsQueryKeys.one({ setId }))\n}\n\nexport function updateSetInCache({\n set,\n queryClient,\n}: {\n set: SetWithId\n queryClient: QueryClient\n}) {\n const { id, ...setData } = set\n\n queryClient.setQueryData(setsQueryKeys.one({ setId: id }), setData)\n}\n","const SETS_COLLECTION = 'sets'\n\nexport type RefsSetsFirestore = `${typeof SETS_COLLECTION}/${string}`\n\nexport const refsSetsFirestore = {\n allSets: SETS_COLLECTION,\n set: (id: string) => `${SETS_COLLECTION}/${id}` as const,\n}\n","import { api } from '@core/lib/firebase/api'\nimport { withErrorHandler } from '@core/utils/error-handler'\n\nimport { refsSetsFirestore } from '../set.constants'\nimport { type SetWithId } from '../set.model'\n\nasync function _getSet({ setId }: { setId: string }) {\n const response = await api.getDoc<SetWithId>(refsSetsFirestore.set(setId))\n\n return response.data\n}\n\nexport const getSet = withErrorHandler(_getSet, 'getSet')\n","import { getSet } from './services/get-set.service'\n\nexport const createSetRepo = () => {\n return {\n getSet,\n }\n}\n","/**\n * Configuration thresholds for hallucination detection\n */\nconst HALLUCINATION_THRESHOLDS = {\n // Short repeats\n MIN_CONSECUTIVE_REPEATS: 3,\n MIN_WORDS_FOR_RATIO_CHECK: 10,\n MAX_UNIQUE_WORDS_FOR_RATIO: 3,\n MIN_REPETITION_RATIO: 3,\n\n // Phrase repeats\n MIN_SENTENCE_LENGTH: 10,\n MIN_CONSECUTIVE_SIMILAR_SENTENCES: 2,\n MIN_SENTENCES_FOR_DUPLICATE_CHECK: 3,\n\n // Cyclic patterns\n MIN_CYCLE_LENGTH: 20,\n MIN_CYCLE_REPEATS: 3,\n\n // Entropy detection\n MIN_LENGTH_FOR_ENTROPY_CHECK: 50,\n MAX_ENTROPY_THRESHOLD: 2.5, // bits per character\n\n // Similarity\n SENTENCE_SIMILARITY_THRESHOLD: 0.8,\n SEGMENT_SIMILARITY_THRESHOLD: 0.85,\n} as const\n\n/**\n * Result of hallucination detection with details\n */\nexport interface HallucinationDetectionResult {\n isHallucination: boolean\n reason?: string\n confidence?: number\n}\n\n/**\n * Detects if a transcript contains hallucinated repetitive patterns\n * that Whisper sometimes produces when no clear audio is detected.\n *\n * Common patterns:\n * - \"no, no, no, no...\"\n * - \"yes I did it! yes I did it!...\"\n * - \"Okay, here's what me thinking. Me no like...\"\n *\n * @param transcript - The transcript text to analyze\n * @returns true if hallucination is detected, false otherwise\n */\nexport function detectTranscriptHallucination(transcript: string): boolean {\n const result = detectTranscriptHallucinationWithDetails(transcript)\n\n return result.isHallucination\n}\n\n/**\n * Detects transcript hallucination and provides details about why\n *\n * @param transcript - The transcript text to analyze\n * @returns Detection result with reason and confidence\n */\nexport function detectTranscriptHallucinationWithDetails(\n transcript: string,\n): HallucinationDetectionResult {\n if (!transcript || transcript.trim().length === 0) {\n return { isHallucination: false }\n }\n\n const text = transcript.trim()\n\n // Skip very short transcripts (less than 10 characters)\n if (text.length < 10) {\n return { isHallucination: false }\n }\n\n // 1. Check for very short repeated words/phrases (like \"no, no, no, no\")\n const shortRepeats = detectShortRepeats(text)\n\n if (shortRepeats) {\n return {\n isHallucination: true,\n reason: 'Detected repeated short words or phrases',\n confidence: 0.9,\n }\n }\n\n // 2. Check for repeated sentences or long phrases\n const phraseRepeats = detectPhraseRepeats(text)\n\n if (phraseRepeats) {\n return {\n isHallucination: true,\n reason: 'Detected repeated sentences or phrases',\n confidence: 0.85,\n }\n }\n\n // 3. Check for cyclic patterns (ABC ABC ABC)\n const cyclicRepeats = detectCyclicPattern(text)\n\n if (cyclicRepeats) {\n return {\n isHallucination: true,\n reason: 'Detected cyclic repetition pattern',\n confidence: 0.8,\n }\n }\n\n // 4. Check for low entropy (gibberish or very repetitive text)\n if (text.length >= HALLUCINATION_THRESHOLDS.MIN_LENGTH_FOR_ENTROPY_CHECK) {\n const entropy = calculateEntropy(text)\n\n if (entropy < HALLUCINATION_THRESHOLDS.MAX_ENTROPY_THRESHOLD) {\n return {\n isHallucination: true,\n reason: 'Detected low entropy (likely gibberish or excessive repetition)',\n confidence: 0.75,\n }\n }\n }\n\n return { isHallucination: false }\n}\n\n/**\n * Detects short repeated words like \"no, no, no\" or \"yes, yes, yes\"\n */\nfunction detectShortRepeats(text: string): boolean {\n // Split by punctuation and whitespace\n const words = text\n .toLowerCase()\n .split(/[\\s,;.!?]+/)\n .filter(w => w.length > 0)\n\n if (words.length < 4) return false\n\n // Check for sequences of consecutive identical words\n let repeatCount = 1\n\n for (let i = 1; i < words.length; i++) {\n if (words[i] === words[i - 1]) {\n repeatCount++\n if (repeatCount >= HALLUCINATION_THRESHOLDS.MIN_CONSECUTIVE_REPEATS) {\n return true\n }\n } else {\n repeatCount = 1\n }\n }\n\n // Check if majority of text is just a few words repeated\n const uniqueWords = new Set(words)\n const repetitionRatio = words.length / uniqueWords.size\n\n if (\n words.length >= HALLUCINATION_THRESHOLDS.MIN_WORDS_FOR_RATIO_CHECK &&\n uniqueWords.size <= HALLUCINATION_THRESHOLDS.MAX_UNIQUE_WORDS_FOR_RATIO &&\n repetitionRatio >= HALLUCINATION_THRESHOLDS.MIN_REPETITION_RATIO\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Detects repeated sentences or phrases\n */\nfunction detectPhraseRepeats(text: string): boolean {\n // Split into sentences\n const sentences = text\n .split(/[.!?]+/)\n .map(s => s.trim().toLowerCase())\n .filter(s => s.length > HALLUCINATION_THRESHOLDS.MIN_SENTENCE_LENGTH)\n\n if (sentences.length < 2) return false\n\n // Check for consecutive sentence repetition\n for (let i = 0; i < sentences.length - 1; i++) {\n let consecutiveRepeats = 1\n\n for (let j = i + 1; j < sentences.length; j++) {\n if (isSimilarSentence(sentences[i], sentences[j])) {\n consecutiveRepeats++\n } else {\n break\n }\n }\n\n if (consecutiveRepeats >= HALLUCINATION_THRESHOLDS.MIN_CONSECUTIVE_SIMILAR_SENTENCES) {\n return true\n }\n }\n\n // Check if majority of sentences are duplicates\n const uniqueSentences = new Set(sentences)\n\n if (\n sentences.length >= HALLUCINATION_THRESHOLDS.MIN_SENTENCES_FOR_DUPLICATE_CHECK &&\n uniqueSentences.size === 1\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Check if two sentences are similar (allowing for minor variations)\n */\nfunction isSimilarSentence(\n s1: string,\n s2: string,\n threshold: number = HALLUCINATION_THRESHOLDS.SENTENCE_SIMILARITY_THRESHOLD,\n): boolean {\n // Exact match\n if (s1 === s2) return true\n\n // Remove extra spaces and compare\n const normalized1 = s1.replace(/\\s+/g, ' ').trim()\n const normalized2 = s2.replace(/\\s+/g, ' ').trim()\n\n if (normalized1 === normalized2) return true\n\n // Check similarity by word overlap (Sørensen-Dice coefficient)\n const words1 = normalized1.split(/\\s+/)\n const words2 = normalized2.split(/\\s+/)\n\n // If lengths differ significantly, not similar\n if (Math.abs(words1.length - words2.length) > 2) return false\n\n // Calculate word overlap using Sørensen-Dice coefficient\n const set1 = new Set(words1)\n const set2 = new Set(words2)\n const intersection = new Set([...set1].filter(w => set2.has(w)))\n\n const similarity = (intersection.size * 2) / (set1.size + set2.size)\n\n return similarity >= threshold\n}\n\n/**\n * Detects cyclic repetition patterns (e.g., \"ABC ABC ABC\")\n * Optimized to check fewer cycle lengths and use more appropriate similarity metric\n */\nfunction detectCyclicPattern(text: string): boolean {\n const normalized = text.toLowerCase().replace(/\\s+/g, ' ').trim()\n const length = normalized.length\n\n // Try different cycle lengths\n const minCycleLength = HALLUCINATION_THRESHOLDS.MIN_CYCLE_LENGTH\n const maxCycleLength = Math.floor(length / 2)\n\n if (maxCycleLength < minCycleLength) return false\n\n // Optimize: Check fewer cycle lengths (every 5 chars instead of every char)\n const step = 5\n\n for (let cycleLen = minCycleLength; cycleLen <= maxCycleLength; cycleLen += step) {\n const pattern = normalized.substring(0, cycleLen)\n let matchCount = 0\n let pos = 0\n\n // Count how many times this pattern repeats\n while (pos < length) {\n const segment = normalized.substring(pos, pos + cycleLen)\n\n if (segment.length < cycleLen) {\n // Handle the last partial segment\n const partialMatch = pattern.startsWith(segment)\n\n if (partialMatch && matchCount > 0) {\n matchCount++\n }\n break\n }\n\n // Use character-level similarity for segments (not word-level)\n if (segment === pattern || isSegmentSimilar(segment, pattern)) {\n matchCount++\n pos += cycleLen\n } else {\n break\n }\n }\n\n if (matchCount >= HALLUCINATION_THRESHOLDS.MIN_CYCLE_REPEATS) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Checks if two text segments are similar using character-level comparison\n * More appropriate than word-level comparison for arbitrary text segments\n */\nfunction isSegmentSimilar(s1: string, s2: string): boolean {\n if (s1 === s2) return true\n if (s1.length !== s2.length) return false\n\n // Calculate character-level similarity (Levenshtein-like but simpler)\n let matches = 0\n const minLength = Math.min(s1.length, s2.length)\n\n for (let i = 0; i < minLength; i++) {\n if (s1[i] === s2[i]) {\n matches++\n }\n }\n\n const similarity = matches / minLength\n\n return similarity >= HALLUCINATION_THRESHOLDS.SEGMENT_SIMILARITY_THRESHOLD\n}\n\n/**\n * Calculates Shannon entropy of text (in bits per character)\n * Lower entropy indicates more repetitive or predictable text\n *\n * @param text - Text to analyze\n * @returns Entropy value (typically 0-8 bits for text)\n */\nfunction calculateEntropy(text: string): number {\n if (!text || text.length === 0) {\n return 0\n }\n\n // Count character frequencies\n const frequencies = new Map<string, number>()\n\n for (const char of text.toLowerCase()) {\n frequencies.set(char, (frequencies.get(char) || 0) + 1)\n }\n\n // Calculate Shannon entropy: H = -Σ(p(x) * log2(p(x)))\n let entropy = 0\n const length = text.length\n\n for (const count of frequencies.values()) {\n const probability = count / length\n\n entropy -= probability * Math.log2(probability)\n }\n\n return entropy\n}\n\n/**\n * Cleans a transcript by detecting and removing hallucinations\n * Returns empty string if hallucination detected, otherwise returns original transcript\n */\nexport function cleanHallucinatedTranscript(transcript: string): string {\n const result = detectTranscriptHallucinationWithDetails(transcript)\n\n if (result.isHallucination) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Hallucinated transcript detected and removed:',\n transcript.substring(0, 100),\n `\\nReason: ${result.reason ?? 'Unknown'}`,\n `Confidence: ${String(result.confidence ?? 'Unknown')}`,\n )\n\n return ''\n }\n\n return transcript\n}\n","import { api } from '@core/lib/firebase/api'\n\nimport { cleanHallucinatedTranscript } from './detect-transcript-hallucionation'\n\nexport async function getTranscript(\n model: 'gemini' | 'assemblyai' | 'whisper',\n args: {\n language: string\n audioUrl: string\n prompt?: string\n },\n cleanHallucinations = true,\n) {\n const getGeminiTranscript = api.httpsCallable?.('getGeminiTranscript')\n const getAssemblyAITranscript = api.httpsCallable?.('transcribeAssemblyAIAudio')\n const getWhisperTranscript = api.httpsCallable?.('transcribeAudio')\n\n if (model === 'whisper') {\n try {\n const { data } = (await getWhisperTranscript?.({\n audioUrl: args.audioUrl,\n language: args.language,\n })) as {\n data: string\n }\n\n return cleanHallucinations ? cleanHallucinatedTranscript(data) : data\n } catch (error) {\n console.error('Error getting transcript from Whisper:', error)\n throw error\n }\n }\n\n if (model === 'gemini') {\n try {\n const { data } = (await getGeminiTranscript?.({\n audioUrl: args.audioUrl,\n targetLanguage: args.language,\n prompt: args.prompt,\n })) as {\n data: {\n transcript: string\n }\n }\n\n return cleanHallucinations ? cleanHallucinatedTranscript(data.transcript) : data.transcript\n } catch (error) {\n console.error('Error getting transcript from Gemini:', error)\n throw error\n }\n }\n\n if (model === 'assemblyai') {\n try {\n const response = (await getAssemblyAITranscript?.({\n audioUrl: args.audioUrl,\n language: args.language,\n })) as {\n data: string\n }\n\n return cleanHallucinations ? cleanHallucinatedTranscript(response.data) : response.data\n } catch (error) {\n console.error('Error getting transcript from AssemblyAI:', error)\n throw error\n }\n }\n\n return null\n}\n\nexport async function getTranscriptCycle(args: {\n audioUrl: string\n language: string\n prompt: string\n}) {\n const models = ['whisper', 'gemini', 'assemblyai'] as const\n let transcript = ''\n let lastError: unknown = null\n\n // Try each model in order until we get a successful transcript\n for (const model of models) {\n try {\n const transcriptResult = await getTranscript(model, args, false)\n const rawTranscript = transcriptResult || ''\n\n transcript = cleanHallucinatedTranscript(rawTranscript)\n\n // If we got a non-empty transcript, we're done\n if (transcript !== '') {\n console.log(`Successfully got transcript from ${model}`)\n break\n }\n\n console.warn(`${model} returned empty transcript, trying next model`)\n } catch (e) {\n console.error(`Error with ${model} transcript:`, e)\n lastError = e\n }\n }\n\n // If all models failed or returned empty strings, show error\n if (transcript === '') {\n console.error('All transcript models failed or returned empty', lastError)\n\n return {\n transcript: '',\n success: false,\n }\n }\n\n return {\n transcript,\n success: true,\n }\n}\n","{\n \"af\": \"Afrikaans\",\n \"sq\": \"Albanian\",\n \"am\": \"Amharic\",\n \"ar\": \"Arabic\",\n \"hy\": \"Armenian\",\n \"az\": \"Azerbaijani\",\n \"eu\": \"Basque\",\n \"be\": \"Belarusian\",\n \"bn\": \"Bengali\",\n \"bs\": \"Bosnian\",\n \"bg\": \"Bulgarian\",\n \"ca\": \"Catalan\",\n \"ceb\": \"Cebuano\",\n \"zh\": \"Chinese\",\n \"co\": \"Corsican\",\n \"hr\": \"Croatian\",\n \"cs\": \"Czech\",\n \"da\": \"Danish\",\n \"nl\": \"Dutch\",\n \"en\": \"English\",\n \"eo\": \"Esperanto\",\n \"et\": \"Estonian\",\n \"fi\": \"Finnish\",\n \"fr\": \"French\",\n \"fy\": \"Frisian\",\n \"gl\": \"Galician\",\n \"ka\": \"Georgian\",\n \"de\": \"German\",\n \"el\": \"Greek\",\n \"gu\": \"Gujarati\",\n \"ht\": \"Haitian Creole\",\n \"ha\": \"Hausa\",\n \"haw\": \"Hawaiian\",\n \"he\": \"Hebrew\",\n \"hi\": \"Hindi\",\n \"hmn\": \"Hmong\",\n \"hu\": \"Hungarian\",\n \"is\": \"Icelandic\",\n \"ig\": \"Igbo\",\n \"id\": \"Indonesian\",\n \"ga\": \"Irish\",\n \"it\": \"Italian\",\n \"ja\": \"Japanese\",\n \"jv\": \"Javanese\",\n \"kn\": \"Kannada\",\n \"kk\": \"Kazakh\",\n \"km\": \"Khmer\",\n \"ko\": \"Korean\",\n \"ku\": \"Kurdish\",\n \"ky\": \"Kyrgyz\",\n \"lo\": \"Lao\",\n \"la\": \"Latin\",\n \"lv\": \"Latvian\",\n \"lt\": \"Lithuanian\",\n \"lb\": \"Luxembourgish\",\n \"mk\": \"Macedonian\",\n \"mg\": \"Malagasy\",\n \"ms\": \"Malay\",\n \"ml\": \"Malayalam\",\n \"mt\": \"Maltese\",\n \"mi\": \"Maori\",\n \"mr\": \"Marathi\",\n \"mn\": \"Mongolian\",\n \"my\": \"Myanmar (Burmese)\",\n \"ne\": \"Nepali\",\n \"no\": \"Norwegian\",\n \"ny\": \"Nyanja (Chichewa)\",\n \"ps\": \"Pashto\",\n \"fa\": \"Persian\",\n \"pl\": \"Polish\",\n \"pt\": \"Portuguese\",\n \"pa\": \"Punjabi\",\n \"ro\": \"Romanian\",\n \"ru\": \"Russian\",\n \"sm\": \"Samoan\",\n \"gd\": \"Scots Gaelic\",\n \"sr\": \"Serbian\",\n \"st\": \"Sesotho\",\n \"sn\": \"Shona\",\n \"sd\": \"Sindhi\",\n \"si\": \"Sinhala (Sinhalese)\",\n \"sk\": \"Slovak\",\n \"sl\": \"Slovenian\",\n \"so\": \"Somali\",\n \"es\": \"Spanish\",\n \"su\": \"Sundanese\",\n \"sw\": \"Swahili\",\n \"sv\": \"Swedish\",\n \"tl\": \"Tagalog (Filipino)\",\n \"tg\": \"Tajik\",\n \"ta\": \"Tamil\",\n \"te\": \"Telugu\",\n \"th\": \"Thai\",\n \"tr\": \"Turkish\",\n \"uk\": \"Ukrainian\",\n \"ur\": \"Urdu\",\n \"uz\": \"Uzbek\",\n \"vi\": \"Vietnamese\",\n \"cy\": \"Welsh\",\n \"xh\": \"Xhosa\",\n \"yi\": \"Yiddish\",\n \"yo\": \"Yoruba\",\n \"zu\": \"Zulu\"\n}","import langs from '@core/constants/all-langs.json'\n\nexport const getRespondCardTool = ({\n language,\n standard = 'actfl',\n}: {\n language: string\n standard: string\n}) => {\n const lang = langs[language as keyof typeof langs] || 'English'\n const tool = {\n tool_choice: {\n type: 'function',\n function: { name: 'get_feedback' },\n },\n tools: [\n {\n type: 'function',\n function: {\n name: 'get_feedback',\n description: \"Get feedback on a student's response\",\n parameters: {\n type: 'object',\n required: [\n 'success',\n 'score',\n 'score_justification',\n 'errors',\n 'improvedResponse',\n 'compliments',\n ],\n properties: {\n success: {\n type: 'boolean',\n description:\n \"Mark true if the student's response was on-topic and generally demonstrated understanding. A few grammar mistakes are acceptable. Mark false if the student's response was off-topic or did not demonstrate understanding.\",\n },\n\n errors: {\n type: 'array',\n items: {\n type: 'object',\n required: ['error', 'grammar_error_type', 'correction', 'justification'],\n properties: {\n error: {\n type: 'string',\n description: \"The grammatical error in the student's response.\",\n },\n correction: {\n type: 'string',\n description: 'The suggested correction to the error',\n },\n justification: {\n type: 'string',\n description: `An explanation of the rationale behind the suggested correction. WRITE THIS IN ${lang}!`,\n },\n grammar_error_type: {\n type: 'string',\n enum: [\n 'subjVerbAgree',\n 'tenseErrors',\n 'articleMisuse',\n 'prepositionErrors',\n 'adjNounAgree',\n 'pronounErrors',\n 'wordOrder',\n 'verbConjugation',\n 'pluralization',\n 'negationErrors',\n 'modalVerbMisuse',\n 'relativeClause',\n 'auxiliaryVerb',\n 'complexSentenceAgreement',\n 'idiomaticExpression',\n 'registerInconsistency',\n 'voiceMisuse',\n ],\n description:\n 'The type of grammatical error found. It should be one of the following categories: subject-verb agreement, tense errors, article misuse, preposition errors, adjective-noun agreement, pronoun errors, word order, verb conjugation, pluralization errors, negation errors, modal verb misuse, relative clause errors, auxiliary verb misuse, complex sentence agreement, idiomatic expression, register inconsistency, or voice misuse',\n },\n },\n },\n description:\n \"An array of objects, each representing a grammatical error in the student's response. Each object should have the following properties: error, grammar_error_type, correction, and justification. If there were no errors, return an empty array.\",\n },\n compliments: {\n type: 'array',\n items: {\n type: 'string',\n },\n description: `An array of strings, each representing something the student did well. Each string should be WRITTEN IN ${lang}!`,\n },\n improvedResponse: {\n type: 'string',\n description:\n 'An improved response with proper grammar and more detail, if applicable.',\n },\n score: {\n type: 'number',\n description:\n 'A score between 0 and 100, reflecting the overall quality of the response',\n },\n score_justification: {\n type: 'string',\n description:\n 'An explanation of the rationale behind the assigned score, considering both accuracy and fluency',\n },\n },\n },\n },\n },\n ],\n }\n\n if (standard === 'wida') {\n // add wida level\n const wida_level = {\n type: 'number',\n enum: [1, 2, 3, 4, 5, 6],\n description: `The student's WIDA (World-Class Instructional Design and Assessment) proficiency level. Choose one of the following options: 1, 2, 3, 4, 5, 6 which corresponds to\n\t\t\t\t\n\t\t\t\t1 - Entering\n\t\t\t\t2 - Emerging\n\t\t\t\t3 - Developing\n\t\t\t\t4 - Expanding\n\t\t\t\t5 - Bridging\n\t\t\t\t6 - Reaching\n\t\t\t\t\n\t\t\tThis is an estimate based on the level of the student's response. Use the descriptions of the WIDA speaking standards to guide your decision.\n\t\t\t\t`,\n }\n const wida_justification = {\n type: 'string',\n description: `An explanation of the rationale behind the assigned WIDA level of the response, considering both accuracy and fluency. WRITE THIS IN ENGLISH!`,\n }\n\n tool.tools[0].function.parameters.required.push('wida_level')\n tool.tools[0].function.parameters.required.push('wida_justification')\n // @ts-ignore\n tool.tools[0].function.parameters.properties.wida_level = wida_level\n // @ts-ignore\n tool.tools[0].function.parameters.properties.wida_justification = wida_justification\n } else {\n const actfl_level = {\n type: 'string',\n enum: ['NL', 'NM', 'NH', 'IL', 'IM', 'IH', 'AL', 'AM', 'AH', 'S', 'D'],\n description:\n \"The student's ACTFL (American Council on the Teaching of Foreign Languages) proficiency level. Choose one of the following options: NL, NM, NH, IL, IM, IH, AL, AM, AH, S, or D\",\n }\n\n const actfl_justification = {\n type: 'string',\n description:\n 'An explanation of the rationale behind the assigned ACTFL level, considering both accuracy and fluency',\n }\n\n tool.tools[0].function.parameters.required.push('actfl_level')\n tool.tools[0].function.parameters.required.push('actfl_justification')\n // @ts-ignore\n tool.tools[0].function.parameters.properties.actfl_level = actfl_level\n // @ts-ignore\n tool.tools[0].function.parameters.properties.actfl_justification = actfl_justification\n }\n\n return tool\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport {\n type AssignmentWithId,\n ActivityPageType,\n type PageScore,\n type Score,\n type ScoreWithId,\n type SetWithId,\n useAssignment,\n useCards,\n useSet,\n} from '@core/domains'\nimport {\n scoreQueryKeys,\n useClearScore,\n useScore,\n useSubmitAssignmentScore,\n useSubmitPracticeScore,\n useUpdateCardScore,\n useUpdateScore,\n} from '@core/domains/assignment/hooks/score-hooks'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { useEffect } from 'react'\nimport { addGradingStandardLog } from '@core/services'\nimport { api } from '@core/lib/firebase/api'\nimport { logOpenActivityPreview, logOpenAssignment } from '@core/lib/firebase/firebase-analytics'\n\nimport { useActivityTracker } from './useActivityTracker'\n\nexport function useActivity({\n id,\n isAssignment,\n onAssignmentSubmitted,\n ltiData,\n}: {\n id: string\n isAssignment: boolean\n onAssignmentSubmitted: (assignmentId: string) => void\n ltiData?: {\n lineItemId?: string\n lti_id?: string\n serviceKey?: string\n }\n}) {\n const { queryClient, user } = useSpeakableApi()\n\n const userId = user.auth.uid\n\n const assignmentQuery = useAssignment({\n assignmentId: id,\n userId: userId,\n enabled: isAssignment,\n })\n\n const activeAssignment = assignmentQuery.data\n\n const setId = isAssignment ? (activeAssignment?.setId ?? '') : id\n\n const querySet = useSet({ setId: setId })\n\n const setData = querySet.data\n\n const assignmentContent = activeAssignment?.content\n const assignmentWeights = activeAssignment?.weights\n\n const setContent = setData?.content\n const setWeights = setData?.weights\n\n const contentCardsToUse = isAssignment ? (assignmentContent ?? setContent) : setContent\n const weightsToUse = isAssignment ? (assignmentWeights ?? setWeights) : setWeights\n\n const activityId = isAssignment ? (activeAssignment?.id ?? '') : setId\n\n const { cardsObject, cardsQueries, cards } = useCards({\n cardIds: contentCardsToUse ?? [],\n enabled: querySet.isSuccess,\n asObject: true,\n })\n\n // Filter out MEDIA_PAGE cards for score updates\n const scorableCardIds = (contentCardsToUse ?? []).filter(cardId => {\n const card = cardsObject?.[cardId]\n\n return card?.type !== ActivityPageType.MEDIA_PAGE\n })\n\n const scoreQuery = useScore({\n isAssignment,\n activityId: id,\n userId,\n courseId: activeAssignment?.courseId,\n googleClassroomUserId: user.profile.googleClassroomUserId,\n enabled: isAssignment ? assignmentQuery.isSuccess : querySet.isSuccess,\n })\n\n const { mutationUpdateScore } = useUpdateScore()\n const { mutationUpdateCardScore } = useUpdateCardScore({\n activityId: activityId,\n isAssignment,\n userId,\n cardIds: scorableCardIds,\n weights: weightsToUse ?? {},\n })\n\n const { mutationClearScore } = useClearScore()\n\n const { submitAssignmentScore } = useSubmitAssignmentScore({\n onAssignmentSubmitted: onAssignmentSubmitted,\n studentName: user.profile.displayName,\n })\n\n const { submitPracticeScore } = useSubmitPracticeScore()\n\n const handleUpdateScore = (data: Partial<Score>) => {\n mutationUpdateScore.mutate({\n data,\n isAssignment,\n activityId: activityId,\n userId,\n })\n }\n\n const handleUpdateCardScore = (cardId: string, cardScore: PageScore) => {\n mutationUpdateCardScore.mutate({ cardId, cardScore })\n\n if (cardScore.proficiency_level) {\n logGradingStandardEntry({\n type: cardScore.proficiency_level.standardId as 'actfl' | 'wida' | 'custom',\n cardId: cardId,\n gradingStandard: cardScore.proficiency_level,\n })\n } else if (cardScore.wida || cardScore.actfl) {\n logGradingStandardEntry({\n type: cardScore.wida ? 'wida' : 'actfl',\n cardId: cardId,\n gradingStandard: cardScore.wida || cardScore.actfl || { level: '', justification: '' },\n })\n }\n }\n\n const onClearScore = ({\n cardId,\n wasCompleted = true,\n }: {\n cardId: string\n wasCompleted?: boolean\n }) => {\n const currentCard = cardsObject?.[cardId]\n\n if (\n currentCard?.type === ActivityPageType.MULTIPLE_CHOICE ||\n currentCard?.type === ActivityPageType.READ_REPEAT\n ) {\n return\n }\n const queryKeys = scoreQueryKeys.byId(activityId)\n const activeCardScores = queryClient.getQueryData<Score>(queryKeys)?.cards?.[cardId]\n\n if (activeCardScores === undefined) return\n\n mutationClearScore.mutate({\n isAssignment,\n activityId: activityId,\n cardScores: activeCardScores,\n cardId,\n userId,\n })\n }\n\n const onSubmitScore = async () => {\n try {\n let results\n\n if (isAssignment) {\n // check card scores if any cards have a \"pending_review\" status\n // past the status to the submitAssignmentScore function\n\n const someCardIsManualGraded = cards.some(page => page.grading_method === 'manual')\n\n results = await submitAssignmentScore({\n assignment: {\n id: assignmentQuery.data?.id ?? '',\n name: assignmentQuery.data?.name ?? '',\n owners: assignmentQuery.data?.owners ?? [],\n courseId: assignmentQuery.data?.courseId ?? '',\n courseWorkId: assignmentQuery.data?.courseWorkId ?? '',\n isAssessment: assignmentQuery.data?.isAssessment ?? false,\n maxPoints: assignmentQuery.data?.maxPoints ?? 0,\n },\n userId: userId,\n cardIds: scorableCardIds,\n scores: scoreQuery.data as Score,\n weights: weightsToUse ?? {},\n status: someCardIsManualGraded ? 'PENDING_REVIEW' : 'SUBMITTED',\n })\n if (assignmentQuery.data?.ltiDeeplink) {\n submitLTIScore({\n maxPoints: assignmentQuery.data?.maxPoints,\n score: scoreQuery.data?.score ?? 0,\n SERVICE_KEY: ltiData?.serviceKey ?? '',\n lineItemId: ltiData?.lineItemId ?? '',\n lti_id: ltiData?.lti_id ?? '',\n })\n }\n\n // if (activeAssignment?.checkpointId) {\n // const submitCheckpointAssignment = httpsCallable(functions, 'submitCheckpointAssignment')\n\n // const results = await submitCheckpointAssignment({\n // checkpointId: activeAssignment.checkpointId,\n // assignmentId: activeAssignment.id,\n // studentId: auth.uid,\n // classroomId: activeAssignment.courseId,\n // teacherId: activeAssignment.owners[0],\n // })\n // console.log('checkpoint assignment results', results)\n // }\n } else {\n results = await submitPracticeScore({\n setId: querySet.data?.id ?? '',\n userId: userId,\n scores: scoreQuery.data!,\n })\n }\n\n return results\n } catch (error) {\n return {\n success: false,\n error: error,\n }\n }\n }\n\n const logGradingStandardEntry = ({\n cardId,\n gradingStandard,\n type,\n }: {\n cardId: string\n gradingStandard: {\n level: string\n justification: string\n }\n type: 'actfl' | 'wida' | 'custom'\n }) => {\n const card = cardsObject?.[cardId]\n const scoresObject = queryClient.getQueryData<ScoreWithId>(scoreQueryKeys.byId(activityId))\n const cardScore = scoresObject?.cards?.[cardId]\n\n const serverTimestamp = api.helpers.serverTimestamp\n\n addGradingStandardLog(\n {\n assignmentId: activeAssignment?.id ?? '',\n courseId: activeAssignment?.courseId ?? '',\n teacherId: activeAssignment?.owners[0] ?? '',\n setId: setData?.id ?? '',\n cardId: cardId,\n level: gradingStandard.level,\n justification: gradingStandard.justification,\n transcript: cardScore?.transcript ?? '',\n audioUrl: cardScore?.audio ?? '',\n prompt: card?.prompt ?? '',\n responseType: card?.type === ActivityPageType.RESPOND_WRITE ? 'written' : 'spoken',\n type: type,\n dateMade: serverTimestamp(),\n language: card?.language ?? '',\n },\n userId,\n )\n }\n\n useEffect(() => {\n if (isAssignment) {\n logOpenAssignment({ assignmentId: id })\n } else {\n logOpenActivityPreview({ setId: id })\n }\n }, [])\n\n useInitActivity({\n assignment: activeAssignment ?? undefined,\n set: setData ?? undefined,\n enabled: !!setData,\n userId,\n })\n\n return {\n set: {\n data: setData,\n query: querySet,\n },\n cards: {\n data: cardsObject,\n query: cardsQueries,\n cardsArray: cards,\n },\n assignment: {\n data: isAssignment ? activeAssignment : undefined,\n query: assignmentQuery,\n },\n scores: {\n data: scoreQuery.data,\n query: scoreQuery,\n actions: {\n update: handleUpdateScore,\n clear: onClearScore,\n submit: onSubmitScore,\n updateCard: handleUpdateCardScore,\n logGradingStandardEntry: logGradingStandardEntry,\n },\n },\n }\n}\n\nconst useInitActivity = ({\n assignment,\n set,\n enabled,\n userId,\n}: {\n assignment?: AssignmentWithId\n set?: SetWithId\n enabled: boolean\n userId: string\n}) => {\n const { trackActivity } = useActivityTracker({ userId: userId })\n\n const init = () => {\n if (!enabled) return\n if (!assignment) {\n trackActivity({\n activityName: set?.name ?? '',\n activityType: 'set',\n id: set?.id,\n language: set?.language,\n })\n } else if (assignment.name) {\n // localStorage.setItem('speakable_course_id', assignment.courseId)\n trackActivity({\n activityName: assignment.name,\n activityType: assignment.isAssessment ? 'assessment' : 'assignment',\n id: assignment.id,\n language: set?.language,\n })\n }\n if (set?.public) {\n api.httpsCallable?.('onSetOpened')?.({\n setId: set.id,\n language: set.language,\n })\n }\n\n api.httpsCallable?.('updateAlgoliaIndex')?.({\n updatePlays: true,\n objectID: set?.id,\n })\n }\n\n useEffect(() => {\n init()\n }, [set])\n}\n\nconst submitLTIScore = async ({\n maxPoints,\n score,\n SERVICE_KEY,\n lineItemId,\n lti_id,\n}: {\n maxPoints: number\n score: number\n SERVICE_KEY: string\n lineItemId: string\n lti_id: string\n}) => {\n try {\n if (!SERVICE_KEY || !lineItemId || !lti_id) {\n throw new Error('Missing required LTI credentials')\n }\n\n const earnedPoints = score ? (score / 100) * maxPoints : 0\n const { data } = await api.httpsCallable?.('submitLTIAssignmentScore')?.({\n SERVICE_KEY,\n scoreData: {\n lineItemId,\n userId: lti_id,\n maxPoints,\n earnedPoints,\n },\n })\n\n return { success: true, data }\n } catch (error) {\n console.error('Failed to submit LTI score:', error)\n\n return {\n success: false,\n error: error instanceof Error ? error : new Error('Unknown error occurred'),\n }\n }\n}\n","import { api } from '@core/lib/firebase/api'\nimport { logGradingStandardLog } from '@core/lib/firebase/firebase-analytics'\nimport { type FieldValue } from 'firebase/firestore'\n\nexport interface GradingStandard {\n type: 'actfl' | 'wida' | 'custom'\n customStandardId?: string | undefined\n dateMade: FieldValue\n courseId?: string\n assignmentId?: string\n teacherId?: string\n cardId: string\n setId: string\n level: string\n justification: string\n prompt: string\n transcript: string\n audioUrl?: string\n responseType: 'spoken' | 'written'\n language: string\n}\n\nexport const addGradingStandardLog = async (gradingStandard: GradingStandard, userId: string) => {\n logGradingStandardLog(gradingStandard)\n const path = `users/${userId}/grading_standard_logs`\n\n await api.addDoc(path, gradingStandard)\n}\n","import { api } from '@core/lib/firebase/api'\nimport { v4 } from 'uuid'\n\nexport function useActivityTracker({ userId }: { userId: string }) {\n const trackActivity = async ({\n activityName,\n activityType,\n id = v4(),\n language = '',\n }: {\n activityName: string\n activityType: 'assignment' | 'assessment' | 'set'\n id?: string\n language?: string\n }) => {\n if (userId) {\n const { doc, serverTimestamp, setDoc } = api.accessHelpers()\n\n const activityRef = doc(`users/${userId}/activity/${id}`)\n\n const timestamp = serverTimestamp()\n\n await setDoc(activityRef, {\n name: activityName,\n type: activityType,\n lastSeen: timestamp,\n id,\n language,\n })\n }\n }\n\n return {\n trackActivity,\n }\n}\n","import { api } from '@core/lib/firebase/api'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { useQuery } from '@tanstack/react-query'\n\nexport interface CreditContract {\n allocationSource: string\n createdAt: string\n creditsAllocatedThisPeriod: number\n effectivePlanId: string\n email: string\n isUnlimited: boolean\n lastUpdatedAt: string // Formato de fecha ISO o timestamp\n ownerType: string\n periodStart: string // Formato de fecha ISO o timestamp\n periodEnd: string // Formato de fecha ISO o timestamp\n planTermEndTimestamp: string | null\n sourceDetails: Record<string, unknown>\n creditsAvailable?: number\n topOffCreditsAvailable?: number\n}\n\nexport const creditQueryKeys = {\n userCredits: (uid: string) => ['userCredits', uid] as const,\n}\n\nexport const useUserCredits = () => {\n const { user } = useSpeakableApi()\n\n const email = user.auth.email\n const uid = user.auth.uid\n\n const query = useQuery({\n queryKey: creditQueryKeys.userCredits(uid),\n queryFn: () => fetchUserCredits({ uid, email }),\n enabled: !!uid,\n refetchInterval: 1000 * 60 * 5,\n })\n\n return {\n ...query,\n }\n}\n\nconst fetchUserCredits = async ({ uid, email }: { uid: string; email: string }) => {\n if (!uid) {\n throw new Error('User ID is required')\n }\n\n const contractSnap = await api.getDoc<CreditContract>(`creditContracts/${uid}`)\n\n if (contractSnap.data == null) {\n return {\n id: uid,\n userId: uid,\n email: email,\n effectivePlanId: 'free_tier',\n status: 'inactive',\n isUnlimited: false,\n creditsAvailable: 100,\n creditsAllocatedThisPeriod: 100,\n topOffCreditsAvailable: 0,\n topOffCreditsTotal: 0,\n allocationSource: 'free_tier',\n sourceDetails: {},\n periodStart: null,\n periodEnd: null,\n planTermEndTimestamp: null,\n ownerType: 'individual',\n createdAt: new Date().toISOString(),\n lastUpdatedAt: new Date().toISOString(),\n }\n }\n\n const contractData = contractSnap.data\n\n // Calculate total available credits using existing fields\n //@ts-ignore\n const monthlyCredits = contractData?.creditsAvailable || 0\n //@ts-ignore\n const topOffCredits = contractData?.topOffCreditsAvailable || 0\n const totalCredits = monthlyCredits + topOffCredits\n\n return {\n id: contractSnap.id,\n ...contractData,\n // Add computed total for convenience\n totalCreditsAvailable: totalCredits,\n }\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { api } from '@core/lib/firebase/api'\n\nexport interface OrganizationAccess {\n hasUnlimitedAccess: boolean\n subscriptionId: string | null\n organizationId: string | null\n organizationName: string | null\n subscriptionEndDate: Date | null\n accessType: 'organization' | 'individual' | 'institution_subscriptions'\n}\n\nexport interface InstitutionSubscription {\n id: string\n institutionId: string\n name: string\n plan: string\n endDate: Date\n}\n\nexport interface Organization {\n id: string\n name: string\n members: string[]\n masterSubscriptionStatus: string\n masterSubscriptionId: string\n masterSubscriptionEndDate: Date\n}\n\nexport const useOrganizationAccess = () => {\n const { user } = useSpeakableApi()\n\n const email = user.auth.email\n\n const query = useQuery({\n queryKey: ['organizationAccess', email],\n queryFn: async (): Promise<OrganizationAccess> => {\n if (!email) {\n return {\n hasUnlimitedAccess: false,\n subscriptionId: null,\n organizationId: null,\n organizationName: null,\n subscriptionEndDate: null,\n accessType: 'individual',\n }\n }\n\n return getOrganizationAccess(email)\n },\n enabled: !!email, // Only run query if we have a user email\n staleTime: 5 * 60 * 1000, // Consider data fresh for 5 minutes\n gcTime: 10 * 60 * 1000, // Keep in cache for 10 minutes\n retry: 2, // Retry failed requests twice\n })\n\n return {\n ...query,\n }\n}\n\nconst getOrganizationAccess = async (email: string): Promise<OrganizationAccess> => {\n const { limit, where } = api.accessQueryConstraints()\n\n try {\n const organizationSnapshot = await api.getDocs<Organization>(\n 'organizations',\n where('members', 'array-contains', email),\n where('masterSubscriptionStatus', '==', 'active'),\n limit(1),\n )\n\n if (!organizationSnapshot.empty) {\n // User is a member of an organization with active subscription\n const orgData = organizationSnapshot.data[0]\n\n return {\n hasUnlimitedAccess: true,\n subscriptionId: orgData?.masterSubscriptionId,\n organizationId: orgData.id,\n organizationName: orgData.name || 'Unknown Organization',\n subscriptionEndDate: orgData.masterSubscriptionEndDate || null,\n accessType: 'organization',\n }\n }\n\n // Check legacy institution subscriptions\n\n const institutionSnapshot = await api.getDocs<InstitutionSubscription>(\n 'institution_subscriptions',\n where('users', 'array-contains', email),\n where('active', '==', true),\n limit(1),\n )\n\n if (!institutionSnapshot.empty) {\n // User has legacy institution subscription\n const institutionData = institutionSnapshot.data[0]\n const isUnlimited =\n institutionData?.plan === 'organization' || institutionData?.plan === 'school_starter'\n\n return {\n hasUnlimitedAccess: isUnlimited,\n subscriptionId: institutionData.id,\n organizationId: institutionData?.institutionId,\n organizationName:\n institutionData.name || institutionData.institutionId || 'Legacy Institution',\n subscriptionEndDate: institutionData.endDate || null,\n accessType: 'institution_subscriptions',\n }\n }\n\n // No organization or legacy subscription access found\n return {\n hasUnlimitedAccess: false,\n subscriptionId: null,\n organizationId: null,\n organizationName: null,\n subscriptionEndDate: null,\n accessType: 'individual',\n }\n } catch (error) {\n console.error('Error checking organization access:', error)\n\n // Return individual access on error to be safe\n return {\n hasUnlimitedAccess: false,\n subscriptionId: null,\n organizationId: null,\n organizationName: null,\n subscriptionEndDate: null,\n accessType: 'individual',\n }\n }\n}\n","import { getTranscript, getTranscriptCycle } from '@core/utils'\nimport { useMutation } from '@tanstack/react-query'\n\nexport function useSpeakableTranscript() {\n const mutation = useMutation({\n mutationFn: async ({\n model,\n audioUrl,\n language,\n prompt,\n }: {\n model: 'gemini' | 'assemblyai' | 'whisper'\n audioUrl: string\n language: string\n prompt?: string\n }) => {\n return getTranscript(model, { audioUrl, language, prompt })\n },\n retry: false,\n })\n\n return {\n mutation,\n }\n}\n\nexport function useSpeakableTranscriptCycle() {\n const mutation = useMutation({\n mutationFn: async (args: { audioUrl: string; language: string; prompt: string }) => {\n return getTranscriptCycle(args)\n },\n retry: false,\n })\n\n return {\n mutationTranscriptCycle: mutation,\n }\n}\n","import { type PageActivityWithId } from '@core/domains'\nimport { api } from '@core/lib/firebase/api'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { cleanString, getPhraseLength, getWordHash } from '@core/utils'\n\nexport const useUpdateStudentVocab = (page: PageActivityWithId | null) => {\n const { user } = useSpeakableApi()\n\n const currentUserId = user?.auth.uid\n\n if (!page || !currentUserId || !page.target_text || !page.language) {\n return {\n studentVocabMarkVoiceSuccess: undefined,\n studentVocabMarkVoiceFail: undefined,\n }\n }\n\n const getDataObject = () => {\n const { serverTimestamp } = api.accessHelpers()\n\n const language = page.language ?? 'en'\n const word = page.target_text ?? ''\n const phrase_length = getPhraseLength(word)\n const wordHash = getWordHash(word, language)\n const docPath = `users/${currentUserId}/vocab/${wordHash}`\n const communityPath = `checked-pronunciations/${wordHash}`\n\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n const id = `${language}-${cleanString(word)}`\n const data = {\n id: id,\n word: word,\n words: word?.split(' ') || [],\n wordHash: wordHash,\n language: language,\n lastSeen: serverTimestamp(),\n phrase_length: phrase_length,\n }\n\n return {\n docPath,\n communityPath,\n data,\n }\n }\n\n const markVoiceSuccess = async () => {\n const { docPath, communityPath, data } = getDataObject()\n const { increment } = api.accessQueryConstraints()\n const { serverTimestamp } = api.accessHelpers()\n\n // @ts-ignore\n data.voiceSuccess = increment(1)\n try {\n await api.updateDoc(docPath, data)\n } catch (error) {\n if (error instanceof Error && error.message === 'not-found') {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n data.firstSeen = serverTimestamp()\n await api.setDoc(docPath, data, { merge: true })\n } else {\n console.log(error)\n }\n }\n\n try {\n // @ts-ignore\n data.pronunciations = increment(1)\n await api.setDoc(communityPath, data, { merge: true })\n } catch (error) {\n console.log(error)\n }\n }\n\n const markVoiceFail = async () => {\n const { docPath, communityPath, data } = getDataObject()\n const { increment } = api.accessQueryConstraints()\n const { serverTimestamp } = api.accessHelpers()\n\n // @ts-ignore\n data.voiceFail = increment(1)\n try {\n await api.updateDoc(docPath, data)\n } catch (error) {\n if (error instanceof Error && error.message === 'not-found') {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n data.firstSeen = serverTimestamp()\n await api.setDoc(docPath, data, { merge: true })\n } else {\n console.log(error)\n }\n }\n\n try {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n data.fails = increment(1)\n await api.setDoc(communityPath, data, { merge: true })\n } catch (error) {\n console.log(error)\n }\n }\n\n return {\n studentVocabMarkVoiceSuccess: markVoiceSuccess,\n studentVocabMarkVoiceFail: markVoiceFail,\n }\n}\n","import { api } from '@core/lib/firebase/api'\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { useQuery } from '@tanstack/react-query'\n\nexport interface StudentTeacherPlanResult {\n studentId: string\n teachers: {\n teacherId: string\n teacherName: string\n teacherEmail: string\n plan: string\n hasActiveTeamPlan: boolean\n hasActiveOrgPlan: boolean\n hasUnlimitedAccess: boolean\n }[]\n hasTeacherWithTeamPlan: boolean\n hasTeacherWithOrgPlan: boolean\n hasTeacherWithUnlimitedAccess: boolean\n canAccessFeedback: boolean\n reason?: string\n}\n\nexport interface ActivityFeedbackAccess {\n canAccessFeedback: boolean\n reason?: string\n isUnlimited: boolean\n accessType: 'ai_enabled' | 'teacher_preview' | 'student_with_teacher_plan' | 'none'\n}\n\nexport const activityFeedbackAccessQueryKeys = {\n activityFeedbackAccess: (args: { aiEnabled: boolean; isActivityRoute: boolean }) =>\n ['activityFeedbackAccess', ...Object.values(args)] as const,\n}\n\n/**\n * Hook to check feedback permissions for both students and teachers\n *\n * Permission Logic:\n * 1. aiEnabled: true → Allow feedback access always (highest priority)\n * 2. Teachers on /activity route → Always allowed (ADMIN role)\n * 3. Students on /activity route → Need teacher with active plan (team/org)\n *\n * @param params - Parameters for permission checking\n * @returns Feedback permissions information\n */\n\nexport const useActivityFeedbackAccess = ({\n aiEnabled = false,\n isActivityRoute = false,\n}: {\n aiEnabled?: boolean\n isActivityRoute?: boolean\n}) => {\n const { user } = useSpeakableApi()\n\n const uid = user.auth.uid\n const isTeacher = user.profile?.isTeacher\n const isStudent = user.profile?.isStudent\n const userRoles = user.profile?.roles || []\n\n const query = useQuery({\n queryKey: activityFeedbackAccessQueryKeys.activityFeedbackAccess({\n aiEnabled,\n isActivityRoute,\n }),\n queryFn: async (): Promise<ActivityFeedbackAccess> => {\n if (!uid) {\n return {\n canAccessFeedback: false,\n reason: 'Missing user ID',\n isUnlimited: false,\n accessType: 'none',\n }\n }\n\n try {\n // Priority 1: aiEnabled override (highest priority)\n if (aiEnabled) {\n return {\n canAccessFeedback: true,\n reason: 'AI feedback enabled',\n isUnlimited: true,\n accessType: 'ai_enabled',\n }\n }\n\n // Priority 2: Teachers (preview access) - any teacher can test their creations\n if (isTeacher || userRoles.includes('ADMIN')) {\n return {\n canAccessFeedback: true,\n reason: 'Teacher preview access',\n isUnlimited: true,\n accessType: 'teacher_preview',\n }\n }\n\n // Priority 3: Students on /activity route (need teacher with active plan)\n if (isStudent && isActivityRoute) {\n try {\n // Call the cloud function to check student teacher plans\n\n const result = (await api.httpsCallable?.('checkStudentTeacherPlan')?.({\n studentId: uid,\n })) as {\n data: StudentTeacherPlanResult\n }\n\n const planCheckResult = result.data\n\n if (planCheckResult.canAccessFeedback) {\n return {\n canAccessFeedback: true,\n reason: planCheckResult.reason || 'Student access via teacher with active plan',\n isUnlimited: planCheckResult.hasTeacherWithUnlimitedAccess,\n accessType: 'student_with_teacher_plan',\n }\n } else {\n return {\n canAccessFeedback: false,\n reason: planCheckResult.reason || 'No teacher with active plan found',\n isUnlimited: false,\n accessType: 'none',\n }\n }\n } catch (error: unknown) {\n console.error('Error checking student teacher plan:', error)\n\n return {\n canAccessFeedback: false,\n reason: 'Error checking teacher plans',\n isUnlimited: false,\n accessType: 'none',\n }\n }\n }\n\n // Default: no access\n return {\n canAccessFeedback: false,\n reason: 'No access permissions found for current context',\n isUnlimited: false,\n accessType: 'none',\n }\n } catch (error: unknown) {\n console.error('Error checking activity feedback access:', error)\n\n return {\n canAccessFeedback: false,\n reason: 'Error checking access permissions',\n isUnlimited: false,\n accessType: 'none',\n }\n }\n },\n enabled: !!uid,\n staleTime: 5 * 60 * 1000, // 5 minutes\n gcTime: 10 * 60 * 1000, // 10 minutes\n })\n\n return {\n ...query,\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n\nimport { useSpeakableApi } from '@core/providers/SpeakableProvider'\nimport { getCardFromCache } from '@core/domains'\nimport { getRespondCardTool } from '@core/utils/ai/get-respond-card-tool'\nimport { api } from '@core/lib/firebase/api'\n\nimport { useActivityFeedbackAccess } from './useActivityFeedbackAccess'\n\nexport const useBaseOpenAI = ({\n onTranscriptSuccess,\n onTranscriptError,\n onCompletionSuccess,\n onCompletionError,\n aiEnabled,\n submitAudioResponse,\n uploadAudioAndGetTranscript,\n onGetAudioUrlAndTranscript,\n}: {\n onTranscriptSuccess: (transcript: string) => void\n onTranscriptError: ({ type, message }: { type: string; message: string }) => void\n onCompletionSuccess: (completion: any) => void\n onCompletionError: ({ type, message }: { type: string; message: string }) => void\n aiEnabled: boolean\n submitAudioResponse: (audio: string) => Promise<{ url: string; fileName: string }>\n uploadAudioAndGetTranscript: (\n audio: string,\n language: string,\n pagePrompt: string | null,\n ) => Promise<{\n transcript: string\n audioUrl: string\n }>\n onGetAudioUrlAndTranscript?: (args: { transcript?: string; audioUrl?: string }) => void\n}) => {\n const { user, queryClient } = useSpeakableApi()\n\n const currentUserId = user.auth.uid\n\n const { data: feedbackAccess } = useActivityFeedbackAccess({\n aiEnabled,\n })\n\n const getTranscript = async (audioUrl: string, language: string, prompt?: string) => {\n const getGeminiTranscript = api.httpsCallable?.('getGeminiTranscript')\n const getAssemblyAITranscript = api.httpsCallable?.('transcribeAssemblyAIAudio')\n const getWhisperTranscript = api.httpsCallable?.('transcribeAudio')\n\n try {\n const { data } = await getWhisperTranscript?.({\n audioUrl,\n language: language,\n })\n\n const transcript = data\n\n if (transcript) {\n return transcript\n }\n } catch (error) {\n console.log('Whisper transcript failed, trying Gemini fallback:', error)\n }\n\n try {\n const { data } = await getGeminiTranscript?.({\n audioUrl,\n targetLanguage: language,\n prompt: prompt || '',\n })\n\n const transcript = data.transcript\n\n if (transcript) {\n return transcript\n }\n } catch (error) {\n console.log('Gemini transcript failed, trying AssemblyAI fallback:', error)\n }\n\n try {\n const response = await getAssemblyAITranscript?.({\n audioUrl: audioUrl,\n language: language,\n })\n\n const transcript = response?.data as string\n\n if (transcript) {\n return transcript\n }\n\n throw new Error('Both transcript services failed')\n } catch (error) {\n console.log('AssemblyAI transcript also failed:', error)\n onTranscriptError({\n type: 'TRANSCRIPT',\n message: (error as Error)?.message || 'Error getting transcript from both services',\n })\n\n throw new Error(error as string)\n }\n }\n\n const getFreeResponseCompletion = async (\n messages: string[],\n isFreeResponse: boolean,\n feedbackLanguage: string,\n gradingStandard = 'actfl',\n ) => {\n const responseTool = getRespondCardTool({\n language: feedbackLanguage,\n standard: gradingStandard,\n })\n\n try {\n const createChatCompletion = api.httpsCallable?.('createChatCompletion')\n\n const {\n data: {\n response,\n prompt_tokens = 0,\n completion_tokens = 0,\n success: aiSuccess = false, // the AI was able to generate a response\n },\n } = (await createChatCompletion?.({\n chat: {\n model: isFreeResponse ? 'gpt-4-1106-preview' : 'gpt-3.5-turbo-1106',\n messages: messages,\n temperature: 0.7,\n ...responseTool,\n },\n type: isFreeResponse ? 'LONG_RESPONSE' : 'SHORT_RESPONSE',\n })) as {\n data: {\n response: any\n prompt_tokens: number\n completion_tokens: number\n success: boolean\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n const functionArguments = JSON.parse(response?.tool_calls?.[0]?.function?.arguments || '{}')\n\n const result = {\n ...functionArguments,\n prompt_tokens,\n completion_tokens,\n aiSuccess,\n }\n\n onCompletionSuccess(result)\n\n return result\n } catch (error) {\n onCompletionError({\n type: 'COMPLETION',\n message: (error as Error)?.message || 'Error getting completion',\n })\n throw new Error(error as string)\n }\n }\n\n const getFeedback = async ({\n cardId,\n language = 'en', // required\n writtenResponse = null, // if the type = RESPOND_WRITE\n audio = null,\n autoGrade = true,\n file = null,\n pagePrompt = null,\n }: {\n cardId: string\n language: string\n writtenResponse: string | null\n audio: string | null\n autoGrade: boolean\n file: string | null\n pagePrompt: string | null\n }) => {\n try {\n // NEW CODE - Check feedback access first\n if (!feedbackAccess?.canAccessFeedback) {\n const result = {\n noFeedbackAvailable: true,\n success: true,\n reason: feedbackAccess?.reason || 'No feedback access',\n accessType: feedbackAccess?.accessType || 'none',\n }\n\n onCompletionSuccess(result)\n\n return result\n }\n\n let transcript\n let audioUrl = undefined\n\n if (writtenResponse) {\n transcript = writtenResponse\n onTranscriptSuccess(writtenResponse)\n } else if (typeof audio === 'string' && file) {\n // NEW CODE - Use feedbackAccess for transcript permission\n if (feedbackAccess?.canAccessFeedback) {\n transcript = await getTranscript(audio, language, pagePrompt ?? '')\n audioUrl = audio\n onTranscriptSuccess(transcript)\n } else {\n console.info(\n `Transcript not available: ${feedbackAccess?.reason || 'No feedback access'}`,\n )\n }\n } else {\n const response = await uploadAudioAndGetTranscript(audio || '', language, pagePrompt ?? '')\n\n transcript = response.transcript\n audioUrl = response.audioUrl\n }\n\n onGetAudioUrlAndTranscript?.({ transcript, audioUrl: audioUrl })\n\n // NEW CODE - Use feedbackAccess instead of plan-based checks\n if (feedbackAccess?.canAccessFeedback) {\n const results = await getAIResponse({\n cardId,\n transcript: transcript || '',\n })\n\n let output = results\n\n if (!autoGrade) {\n output = {\n ...output,\n noFeedbackAvailable: true,\n success: true,\n }\n }\n onCompletionSuccess(output)\n\n return output\n } else {\n const result = {\n noFeedbackAvailable: true,\n success: true,\n reason: feedbackAccess?.reason || 'No feedback access',\n accessType: feedbackAccess?.accessType || 'none',\n }\n\n onCompletionSuccess(result)\n\n return result\n }\n\n // OLD CODE - Commented out for comparison\n // if (AdvancedFeedbackPlans.includes(plan) || BasicFeedbackPlans.includes(plan)) {\n // const results = await getAIResponse({\n // cardId,\n // transcript,\n // autoGrade,\n // feedback_language,\n // })\n // let output = results\n\n // if (!autoGrade) {\n // output = {\n // ...output,\n // noFeedbackAvailable: true,\n // success: true,\n // }\n // }\n // onCompletionSuccess(output)\n\n // return output\n // } else {\n // onCompletionSuccess({\n // noFeedbackAvailable: true,\n // success: true,\n // })\n\n // return {\n // noFeedbackAvailable: true,\n // success: true,\n // }\n // }\n } catch (error) {\n console.error('Error getting feedback:', error)\n throw new Error(error as string)\n }\n }\n\n const getAIResponse = async ({ cardId, transcript }: { cardId: string; transcript: string }) => {\n try {\n const getGeminiFeedback = api.httpsCallable?.('callGetFeedback')\n const getProficiencyEstimate = api.httpsCallable?.('getProficiencyEstimate')\n\n const card = getCardFromCache({\n cardId,\n queryClient,\n })\n\n let feedbackData\n let proficiencyData = {}\n\n if (card && card.grading_method === 'manual') {\n } else if (card && card.grading_method !== 'standards_based') {\n const [geminiResult, proficiencyResult] = await Promise.all([\n getGeminiFeedback?.({\n cardId,\n studentId: currentUserId,\n studentResponse: transcript,\n }),\n getProficiencyEstimate?.({\n cardId,\n studentId: currentUserId,\n studentResponse: transcript,\n }),\n ])\n\n proficiencyData = proficiencyResult?.data || {}\n feedbackData = {\n ...(geminiResult?.data ?? {}),\n // @ts-ignore\n proficiency_level: proficiencyData?.proficiency_level || null,\n }\n } else {\n const geminiResult = await getGeminiFeedback?.({\n cardId,\n studentId: currentUserId,\n studentResponse: transcript,\n })\n\n feedbackData = geminiResult?.data\n }\n\n const results = {\n ...proficiencyData,\n ...feedbackData,\n aiSuccess: true,\n promptSuccess: feedbackData?.success || false,\n transcript,\n }\n\n return results as {\n noFeedbackAvailable: boolean\n success: boolean\n reason: string\n accessType: string\n aiSuccess: boolean\n }\n } catch (error) {\n onCompletionError({\n type: 'AI_FEEDBACK',\n message: (error as Error)?.message || 'Error getting ai feedback',\n })\n throw new Error(error as string)\n }\n }\n\n return {\n submitAudioResponse,\n uploadAudioAndGetTranscript,\n getTranscript,\n getFreeResponseCompletion,\n getFeedback,\n }\n}\n","import {\n getDoc,\n getDocs,\n addDoc,\n setDoc,\n updateDoc,\n deleteDoc,\n runTransaction,\n writeBatch,\n doc,\n collection,\n query,\n serverTimestamp,\n orderBy,\n limit,\n startAt,\n startAfter,\n endAt,\n endBefore,\n where,\n increment,\n} from '@react-native-firebase/firestore'\nimport { type FirestoreHelpers } from '@core/types/firebase.types'\n\nimport { createFsClientBase, type FsClientParams } from './create-firebase-client'\n\nexport const createFsClientNative = ({ db, httpsCallable, logEvent }: FsClientParams) => {\n return createFsClientBase({\n db,\n httpsCallable,\n logEvent,\n helpers: {\n getDoc,\n getDocs,\n addDoc,\n setDoc,\n updateDoc,\n deleteDoc,\n runTransaction,\n writeBatch,\n doc,\n collection,\n query,\n serverTimestamp,\n orderBy,\n limit,\n startAt,\n startAfter,\n endAt,\n endBefore,\n where,\n increment,\n } as unknown as FirestoreHelpers,\n })\n}\n","import { createAssignmentRepo, createCardRepo } from '@core/domains'\nimport {\n type FirestoreHelpers,\n type FirebaseInstance,\n type FirestoreDB,\n type CallableFunction,\n} from '@core/types/firebase.types'\nimport { type Firestore } from 'firebase/firestore'\n\nimport { api } from './firebase/api'\n\nexport type FsClient = ReturnType<typeof createFsClientBase>\n\nexport type FsClientParams = Omit<Parameters<typeof createFsClientBase>[0], 'helpers'>\n\nexport function createFsClientBase({\n db,\n helpers,\n httpsCallable,\n logEvent,\n}: {\n db: FirebaseInstance\n helpers: FirestoreHelpers\n httpsCallable: (name: string) => CallableFunction\n logEvent: (name: string, data: any) => void\n}) {\n const dbAsFirestore = db as FirestoreDB\n\n api.initialize({\n db: dbAsFirestore as Firestore,\n helpers,\n httpsCallable,\n logEvent,\n })\n\n return {\n assignmentRepo: createAssignmentRepo(),\n cardRepo: createCardRepo(),\n }\n}\n"],"mappings":"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","names":["query","orderBy","limit","startAt","startAfter","endAt","endBefore","where","increment","doc","collection","writeBatch","serverTimestamp","setDoc","getDoc","getDocs","addDoc","updateDoc","deleteDoc","runTransaction","useQuery","dayjs","dayjs","serverTimestamp","score","dayjs","dayjs","dayjs","serverTimestamp","dayjs","useQuery","createNotification","useMutation","useQuery","ActivityPageType","FeedbackTypesCard","LeniencyCard","VerificationCardStatus","writeBatch","doc","query","useMutation","useQuery","useQuery","useQuery","useEffect","v4","doc","serverTimestamp","setDoc","submitAssignmentScore","submitPracticeScore","_a","_b","serverTimestamp","useEffect","useQuery","query","useQuery","query","useQuery","limit","where","useMutation","serverTimestamp","increment","useQuery","query","_a","_b","_c","getTranscript"]}