140 lines
4.4 KiB
TypeScript

import { PERSONALITY_QUIZ_KINDS } from '@/shared/constants/personality';
import type { PersonalityQuizResultViewModel } from '@/business/personality/types';
import type { SafetyQuizResultDto } from '@/shared/types/safetyQuiz';
import type { ZoneCheckinTodayDto } from '@/shared/types/zoneCheckins';
export interface ProfileQuizResultRow {
readonly id: string;
readonly quiz: string;
readonly category: string;
readonly result: string;
readonly completed: string;
readonly status: 'complete' | 'pending';
}
export function buildProfileQuizResultRows(
safetyQuizResult: SafetyQuizResultDto | null,
personalityResults: readonly PersonalityQuizResultViewModel[],
zoneCheckinToday: ZoneCheckinTodayDto | null = null,
includeZoneCheckin = true,
): readonly ProfileQuizResultRow[] {
const rows: ProfileQuizResultRow[] = [
toProfileSafetyQuizRow(safetyQuizResult),
...personalityResults.map(toProfilePersonalityQuizRow),
];
if (!hasPersonalityResult(personalityResults, PERSONALITY_QUIZ_KINDS.selfAssessment)) {
rows.push(toProfilePendingPersonalityQuizRow(PERSONALITY_QUIZ_KINDS.selfAssessment));
}
if (!hasPersonalityResult(personalityResults, PERSONALITY_QUIZ_KINDS.personalityType)) {
rows.push(toProfilePendingPersonalityQuizRow(PERSONALITY_QUIZ_KINDS.personalityType));
}
if (includeZoneCheckin) {
rows.push(toProfileZoneCheckinRow(zoneCheckinToday));
}
return rows;
}
function hasPersonalityResult(
results: readonly PersonalityQuizResultViewModel[],
quizKind: PersonalityQuizResultViewModel['quizKind'],
): boolean {
return results.some((result) => result.quizKind === quizKind);
}
function getPersonalityResultSummary(result: PersonalityQuizResultViewModel): string {
if (result.quizKind === PERSONALITY_QUIZ_KINDS.personalityType) {
return result.personalityType ?? result.resultLabel ?? 'Completed';
}
const label = result.resultLabel ?? 'Completed';
if (result.score === null) {
return label;
}
return `${label} (${result.score}/${result.totalQuestions * 4})`;
}
function getResultCategoryLabel(result: PersonalityQuizResultViewModel): string {
return result.quizKind === PERSONALITY_QUIZ_KINDS.personalityType
? 'Personality type'
: 'EI self-assessment';
}
function toProfileSafetyQuizRow(result: SafetyQuizResultDto | null): ProfileQuizResultRow {
if (!result) {
return {
id: 'behavior-management-pending',
quiz: 'Behavior Management',
category: 'QBS safety quiz',
result: 'Pending',
completed: 'Not completed',
status: 'pending',
};
}
return {
id: `${result.id}-behavior-management`,
quiz: result.quiz_title,
category: 'QBS safety quiz',
result: `${result.score}/${result.total_questions}`,
completed: new Date(result.completed_at).toLocaleDateString(),
status: 'complete',
};
}
function toProfilePersonalityQuizRow(result: PersonalityQuizResultViewModel): ProfileQuizResultRow {
return {
id: `${result.quizKind}-${result.quizId}-${result.completedAt}`,
quiz: result.quizTitle,
category: getResultCategoryLabel(result),
result: getPersonalityResultSummary(result),
completed: new Date(result.completedAt).toLocaleDateString(),
status: 'complete',
};
}
function toProfilePendingPersonalityQuizRow(
quizKind: typeof PERSONALITY_QUIZ_KINDS.selfAssessment | typeof PERSONALITY_QUIZ_KINDS.personalityType,
): ProfileQuizResultRow {
return {
id: `${quizKind}-pending`,
quiz: quizKind === PERSONALITY_QUIZ_KINDS.personalityType
? 'Personality Type Quiz'
: 'EI Self-Assessment',
category: quizKind === PERSONALITY_QUIZ_KINDS.personalityType
? 'Personality type'
: 'EI self-assessment',
result: 'Pending',
completed: 'Not completed',
status: 'pending',
};
}
function toProfileZoneCheckinRow(
checkin: ZoneCheckinTodayDto | null,
): ProfileQuizResultRow {
if (!checkin?.zone) {
return {
id: 'daily-zone-check-in-pending',
quiz: 'Daily Zone Check-In',
category: 'Regulation zone',
result: 'Pending',
completed: 'Not completed',
status: 'pending',
};
}
return {
id: `daily-zone-check-in-${checkin.date}`,
quiz: 'Daily Zone Check-In',
category: 'Regulation zone',
result: `${checkin.zone[0].toUpperCase()}${checkin.zone.slice(1)} Zone`,
completed: new Date(`${checkin.date}T00:00:00`).toLocaleDateString(),
status: 'complete',
};
}