diff --git a/app/components/create-settings.hbs b/app/components/create-settings.hbs new file mode 100644 index 0000000..e458468 --- /dev/null +++ b/app/components/create-settings.hbs @@ -0,0 +1,113 @@ +
+ + + + + + + + + + +
+
+ +
+
+ +
+
+ + + + +

+ {{t "error.poll.savingFailed.description"}} +

+
+ + + {{t "action.abort"}} + + + {{t "modal.save-retry.button-retry"}} + + +
+
+
\ No newline at end of file diff --git a/app/components/create-settings.ts b/app/components/create-settings.ts new file mode 100644 index 0000000..dd1aa31 --- /dev/null +++ b/app/components/create-settings.ts @@ -0,0 +1,188 @@ +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; +import { service } from '@ember/service'; +import { isPresent } from '@ember/utils'; +import { DateTime, Duration } from 'luxon'; +import { generatePassphrase } from '../utils/encryption'; +import Poll from '../models/poll'; +import type IntlService from 'ember-intl/services/intl'; +import type RouterService from '@ember/routing/router-service'; +import type { CreateSettingsRouteModel } from 'croodle/routes/create/settings'; + +export interface CreateSettingsSignature { + Args: { + poll: CreateSettingsRouteModel; + }; +} + +export default class CreateSettingsComponent extends Component { + @service declare intl: IntlService; + @service declare router: RouterService; + + @tracked savingPollFailed = false; + + get anonymousUser() { + return this.args.poll.anonymousUser; + } + set anonymousUser(value) { + this.args.poll.anonymousUser = value; + } + + get answerType() { + return this.args.poll.answerType; + } + set answerType(value) { + this.args.poll.answerType = value; + } + + get answerTypes() { + return [ + { id: 'YesNo', labelTranslation: 'answerTypes.yesNo.label' }, + { id: 'YesNoMaybe', labelTranslation: 'answerTypes.yesNoMaybe.label' }, + { id: 'FreeText', labelTranslation: 'answerTypes.freeText.label' }, + ]; + } + + get expirationDuration() { + // TODO: must be calculated based on model.expirationDate + return 'P3M'; + } + set expirationDuration(value) { + this.args.poll.expirationDate = isPresent(value) + ? (DateTime.local().plus(Duration.fromISO(value)).toISO() as string) + : ''; + } + + get expirationDurations() { + return [ + { + id: 'P7D', + labelTranslation: 'create.settings.expirationDurations.P7D', + }, + { + id: 'P1M', + labelTranslation: 'create.settings.expirationDurations.P1M', + }, + { + id: 'P3M', + labelTranslation: 'create.settings.expirationDurations.P3M', + }, + { + id: 'P6M', + labelTranslation: 'create.settings.expirationDurations.P6M', + }, + { + id: 'P1Y', + labelTranslation: 'create.settings.expirationDurations.P1Y', + }, + { id: '', labelTranslation: 'create.settings.expirationDurations.never' }, + ]; + } + + get forceAnswer() { + return this.args.poll.forceAnswer; + } + set forceAnswer(value) { + this.args.poll.forceAnswer = value; + } + + @action + previousPage() { + const { pollType } = this.args.poll; + + if (pollType === 'FindADate') { + this.router.transitionTo('create.options-datetime'); + } else { + this.router.transitionTo('create.options'); + } + } + + @action + async createPoll() { + const { poll } = this.args; + const { + anonymousUser, + answerType, + description, + expirationDate, + forceAnswer, + freetextOptions, + dateOptions, + timesForDateOptions, + pollType, + title, + } = poll; + + // calculate options + const options: string[] = []; + if (pollType === 'FindADate') { + // merge date with times + for (const date of dateOptions) { + if (timesForDateOptions.has(date)) { + for (const time of timesForDateOptions.get(date)!) { + const [hour, minute] = time.split(':') as [string, string]; + options.push( + DateTime.fromISO(date) + .set({ + hour: parseInt(hour), + minute: parseInt(minute), + second: 0, + millisecond: 0, + }) + .toISO() as string, + ); + } + } else { + options.push(date); + } + } + } else { + options.push(...freetextOptions); + } + + // save poll + try { + const encryptionKey = generatePassphrase(); + + // save poll + const poll = await Poll.create( + { + anonymousUser, + answerType, + description, + expirationDate, + forceAnswer, + options: options.map((option) => { + return { title: option }; + }), + pollType, + title, + }, + encryptionKey, + ); + + // redirect to new poll + await this.router.transitionTo('poll.participation', poll.id, { + queryParams: { + encryptionKey, + }, + }); + } catch (err) { + this.savingPollFailed = true; + + reportError(err); + } + } + + @action + resetSavingPollFailedState() { + this.savingPollFailed = false; + } +} + +declare module '@glint/environment-ember-loose/registry' { + export default interface Registry { + CreateSettings: typeof CreateSettingsComponent; + } +} diff --git a/app/templates/create/settings.hbs b/app/templates/create/settings.hbs index e458468..6971585 100644 --- a/app/templates/create/settings.hbs +++ b/app/templates/create/settings.hbs @@ -1,113 +1 @@ -
- - - - - - - - - - -
-
- -
-
- -
-
- - - - -

- {{t "error.poll.savingFailed.description"}} -

-
- - - {{t "action.abort"}} - - - {{t "modal.save-retry.button-retry"}} - - -
-
-
\ No newline at end of file + \ No newline at end of file