forked from quic-issues/427e7578-d7bf-49c8-aee9-2dd999e25316
204 lines
5.9 KiB
TypeScript
204 lines
5.9 KiB
TypeScript
/**
|
|
* create-survey.page.ts
|
|
* Page for creating a new survey or editing an existing one.
|
|
*
|
|
* When accessed via /create-survey → creates a new survey
|
|
* When accessed via /create-survey/:id → loads and edits the existing survey
|
|
*/
|
|
|
|
import { Component, OnInit } from '@angular/core';
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
import { ToastController } from '@ionic/angular';
|
|
import { SurveyService } from '../../services/survey.service';
|
|
import type { Survey, Question } from '../../shared/models/survey.models';
|
|
|
|
@Component({
|
|
selector: 'app-create-survey',
|
|
templateUrl: './create-survey.page.html',
|
|
styleUrls: ['./create-survey.page.scss'],
|
|
standalone: false,
|
|
})
|
|
export class CreateSurveyPage implements OnInit {
|
|
/** True when editing an existing survey */
|
|
isEditMode = false;
|
|
existingSurveyId?: string;
|
|
|
|
// Form fields
|
|
title = '';
|
|
description = '';
|
|
questions: Question[] = [];
|
|
|
|
/** Track which question's options are being edited */
|
|
expandedQuestionIndex: number | null = null;
|
|
|
|
constructor(
|
|
private route: ActivatedRoute,
|
|
private router: Router,
|
|
private surveyService: SurveyService,
|
|
private toastCtrl: ToastController
|
|
) {}
|
|
|
|
async ngOnInit(): Promise<void> {
|
|
const id = this.route.snapshot.paramMap.get('id');
|
|
if (id) {
|
|
this.isEditMode = true;
|
|
this.existingSurveyId = id;
|
|
await this.loadSurvey(id);
|
|
} else {
|
|
// Start with one empty question for a better UX
|
|
this.addQuestion();
|
|
}
|
|
}
|
|
|
|
private async loadSurvey(id: string): Promise<void> {
|
|
const survey = await this.surveyService.getSurvey(id);
|
|
if (!survey) {
|
|
const toast = await this.toastCtrl.create({
|
|
message: 'Survey not found.',
|
|
duration: 2000,
|
|
color: 'danger',
|
|
});
|
|
await toast.present();
|
|
this.router.navigate(['/home']);
|
|
return;
|
|
}
|
|
this.title = survey.title;
|
|
this.description = survey.description ?? '';
|
|
// Deep copy so edits don't mutate the original until saved
|
|
this.questions = JSON.parse(JSON.stringify(survey.questions));
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Question management
|
|
// -------------------------------------------------------------------------
|
|
|
|
addQuestion(): void {
|
|
const question: Question = {
|
|
id: crypto.randomUUID(),
|
|
text: '',
|
|
type: 'text',
|
|
required: false,
|
|
};
|
|
this.questions.push(question);
|
|
this.expandedQuestionIndex = this.questions.length - 1;
|
|
}
|
|
|
|
removeQuestion(index: number): void {
|
|
this.questions.splice(index, 1);
|
|
if (this.expandedQuestionIndex === index) {
|
|
this.expandedQuestionIndex = null;
|
|
}
|
|
}
|
|
|
|
moveQuestionUp(index: number): void {
|
|
if (index === 0) return;
|
|
const temp = this.questions[index - 1];
|
|
this.questions[index - 1] = this.questions[index];
|
|
this.questions[index] = temp;
|
|
}
|
|
|
|
moveQuestionDown(index: number): void {
|
|
if (index === this.questions.length - 1) return;
|
|
const temp = this.questions[index + 1];
|
|
this.questions[index + 1] = this.questions[index];
|
|
this.questions[index] = temp;
|
|
}
|
|
|
|
toggleExpand(index: number): void {
|
|
this.expandedQuestionIndex =
|
|
this.expandedQuestionIndex === index ? null : index;
|
|
}
|
|
|
|
onTypeChange(question: Question): void {
|
|
// Initialise options array when switching to multiple_choice
|
|
if (question.type === 'multiple_choice' && !question.options?.length) {
|
|
question.options = ['Option 1', 'Option 2'];
|
|
}
|
|
}
|
|
|
|
addOption(question: Question): void {
|
|
if (!question.options) question.options = [];
|
|
question.options.push(`Option ${question.options.length + 1}`);
|
|
}
|
|
|
|
removeOption(question: Question, optIndex: number): void {
|
|
question.options?.splice(optIndex, 1);
|
|
}
|
|
|
|
trackOption(index: number): number {
|
|
return index;
|
|
}
|
|
|
|
trackQuestion(index: number): number {
|
|
return index;
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Validation
|
|
// -------------------------------------------------------------------------
|
|
|
|
get isFormValid(): boolean {
|
|
if (!this.title.trim()) return false;
|
|
if (this.questions.length === 0) return false;
|
|
return this.questions.every(
|
|
(q) =>
|
|
q.text.trim() &&
|
|
(q.type !== 'multiple_choice' || (q.options && q.options.length >= 2))
|
|
);
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Save / Update
|
|
// -------------------------------------------------------------------------
|
|
|
|
async save(): Promise<void> {
|
|
if (!this.isFormValid) return;
|
|
|
|
const questionsToSave = this.questions.map((q) => ({
|
|
...q,
|
|
text: q.text.trim(),
|
|
// Strip empty options for multiple_choice
|
|
options:
|
|
q.type === 'multiple_choice'
|
|
? q.options?.filter((o) => o.trim()) ?? []
|
|
: undefined,
|
|
}));
|
|
|
|
if (this.isEditMode && this.existingSurveyId) {
|
|
await this.surveyService.updateSurvey(this.existingSurveyId, {
|
|
title: this.title.trim(),
|
|
description: this.description.trim() || undefined,
|
|
questions: questionsToSave,
|
|
});
|
|
const toast = await this.toastCtrl.create({
|
|
message: 'Survey updated.',
|
|
duration: 2000,
|
|
color: 'success',
|
|
});
|
|
await toast.present();
|
|
this.router.navigate(['/survey', this.existingSurveyId]);
|
|
} else {
|
|
const survey = await this.surveyService.createSurvey({
|
|
title: this.title.trim(),
|
|
description: this.description.trim() || undefined,
|
|
questions: questionsToSave,
|
|
});
|
|
const toast = await this.toastCtrl.create({
|
|
message: 'Survey created.',
|
|
duration: 2000,
|
|
color: 'success',
|
|
});
|
|
await toast.present();
|
|
this.router.navigate(['/survey', survey.id]);
|
|
}
|
|
}
|
|
|
|
cancel(): void {
|
|
if (this.isEditMode && this.existingSurveyId) {
|
|
this.router.navigate(['/survey', this.existingSurveyId]);
|
|
} else {
|
|
this.router.navigate(['/home']);
|
|
}
|
|
}
|
|
}
|