forked from quic-issues/427e7578-d7bf-49c8-aee9-2dd999e25316
init
This commit is contained in:
203
src/app/pages/create-survey/create-survey.page.ts
Normal file
203
src/app/pages/create-survey/create-survey.page.ts
Normal file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* 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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user