@sneat/extension-contactus 0.13.0

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.
@@ -0,0 +1,352 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, computed, ViewChild, ChangeDetectionStrategy, Component, effect } from '@angular/core';
3
+ import { NavController, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonCardSubtitle, IonButton, IonSpinner, IonLabel, IonRow, IonGrid, IonCol, IonContent, IonSegment, IonSegmentButton, IonHeader, IonToolbar, IonButtons, IonBackButton, IonTitle } from '@ionic/angular/standalone';
4
+ import { M as MemberService, c as ContactusSpaceContextService, a as ContactusServicesModule } from './sneat-extension-contactus-sneat-extension-contactus-BkVEPHoJ.mjs';
5
+ import { WithNewContactInput, PersonWizardComponent, InviteLinksComponent, NewPetFormComponent } from '@sneat/extension-contactus-ui';
6
+ import { isRelatedPersonReady, RoleSpaceMember } from '@sneat/extension-contactus-contract';
7
+ import { SpacePageBaseComponent } from '@sneat/space-components';
8
+ import { SpaceServiceModule } from '@sneat/space-services';
9
+ import { takeUntil, filter, first } from 'rxjs';
10
+ import * as i1 from '@angular/forms';
11
+ import { UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
12
+ import { namesToUrlParams } from '@sneat/auth-models';
13
+ import { RoutingState, formNexInAnimation } from '@sneat/core';
14
+ import { personNames } from '@sneat/auth-ui';
15
+ import { zipMapBriefsWithIDs } from '@sneat/space-models';
16
+ import { QRCodeComponent } from 'angularx-qrcode';
17
+ import { ClassName } from '@sneat/ui';
18
+
19
+ class NewMemberFormComponent extends WithNewContactInput {
20
+ personRequirements = {
21
+ ageGroup: { required: true },
22
+ gender: { required: true },
23
+ };
24
+ navController = inject(NavController);
25
+ hasNavHistory;
26
+ $isSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "$isSubmitting" }] : /* istanbul ignore next */ []));
27
+ $canSubmit = computed(() => this.$spaceRef().id &&
28
+ !this.$isSubmitting() &&
29
+ this.$isContactReady() &&
30
+ !this.addMemberForm.disabled && //TODO(check) Could be a problem with Push detection strategy?
31
+ this.addMemberForm.valid, ...(ngDevMode ? [{ debugName: "$canSubmit" }] : /* istanbul ignore next */ []));
32
+ $qrData = computed(() => {
33
+ const contact = this.$contact();
34
+ let url = `https://sneat.app/pwa/join?family=${contact.space.id}`;
35
+ const { gender, ageGroup } = contact.dbo;
36
+ if (gender &&
37
+ gender !== 'unknown' &&
38
+ gender !== 'undisclosed' &&
39
+ gender !== 'other') {
40
+ url += '&gender=' + gender;
41
+ }
42
+ if (ageGroup) {
43
+ url += '&ageGroup=' + ageGroup;
44
+ }
45
+ url += namesToUrlParams(contact.dbo.names);
46
+ url += '&utm_source=sneat.app&utm_medium=qr_code&utm_campaign=new_member';
47
+ return url;
48
+ }, ...(ngDevMode ? [{ debugName: "$qrData" }] : /* istanbul ignore next */ []));
49
+ contactusSpace;
50
+ $isContactReady = computed(() => {
51
+ const contact = this.$contact();
52
+ return (contact && isRelatedPersonReady(contact.dbo, this.personRequirements));
53
+ }, ...(ngDevMode ? [{ debugName: "$isContactReady" }] : /* istanbul ignore next */ []));
54
+ personFormComponent;
55
+ // @ViewChild('emailInput', { static: false }) emailInput?: IonInput;
56
+ // @ViewChild('genderFirstInput', { static: false }) genderFirstInput?: IonRadio;
57
+ // public get isPersonFormReady(): boolean {
58
+ // return isRelatedPersonNotReady(this.member, this.personRequirements);
59
+ // }
60
+ //
61
+ // public readonly setFocusToInput = createSetFocusToInput(
62
+ // this.params.errorLogger,
63
+ // );
64
+ // public readonly memberType = new FormControl<TeamMemberType>('member', [
65
+ // Validators.required,
66
+ // ]);
67
+ addMemberForm = new UntypedFormGroup({
68
+ // email: this.email,
69
+ // phone: this.phone,
70
+ // ageGroup: this.ageGroup,
71
+ // relationship: this.relationship,
72
+ });
73
+ memberService = inject(MemberService);
74
+ constructor() {
75
+ super();
76
+ const routingState = inject(RoutingState);
77
+ this.hasNavHistory = routingState.hasHistory();
78
+ }
79
+ ngOnChanges(changes) {
80
+ if (changes['$space']) {
81
+ this.setPersonRequirements(this.$contact());
82
+ }
83
+ }
84
+ setPersonRequirements(contact) {
85
+ const spaceRef = this.$spaceRef();
86
+ this.personRequirements = {
87
+ // TODO: Should we move it inside person form wizard?
88
+ ...this.personRequirements,
89
+ ageGroup: spaceRef.type === 'family' && contact.dbo.type !== 'animal'
90
+ ? { required: true }
91
+ : { hide: true },
92
+ roles: spaceRef.type === 'family' && contact.dbo.type !== 'animal'
93
+ ? { hide: true }
94
+ : { required: true },
95
+ relatedAs: spaceRef.type === 'family' && contact.dbo.type !== 'animal'
96
+ ? { required: true }
97
+ : { hide: true },
98
+ };
99
+ }
100
+ submit() {
101
+ // if (!this.hasNames) {
102
+ // alert('Please enter first or last or full name of the new member');
103
+ // if (!this.firstName.value && !this.lastName.value) {
104
+ // this.setFocusToInput(this.firstNameInput);
105
+ // } else {
106
+ // this.setFocusToInput(this.fullNameInput);
107
+ // }
108
+ // return;
109
+ // }
110
+ if (!this.personFormComponent) {
111
+ throw '!this.personFormComponent';
112
+ }
113
+ const spaceRef = this.$spaceRef();
114
+ const contact = this.$contact();
115
+ if (!spaceRef?.id) {
116
+ this.errorLogger.logError('not able to add new member without space context');
117
+ return;
118
+ }
119
+ if (!contact) {
120
+ this.errorLogger.logError('member field is undefined');
121
+ return;
122
+ }
123
+ if (this.personRequirements.ageGroup?.required && !contact.dbo.ageGroup) {
124
+ throw new Error('Age group is a required field');
125
+ }
126
+ if (this.personRequirements.gender?.required && !contact.dbo.gender) {
127
+ throw new Error('Gender is a required field');
128
+ }
129
+ const displayName = personNames(contact.dbo.names);
130
+ const duplicateMember = zipMapBriefsWithIDs(this.contactusSpace?.dbo?.contacts)?.find((m) => personNames(m.brief.names) === displayName);
131
+ if (duplicateMember) {
132
+ alert('There is already a member with same name: ' + displayName);
133
+ return;
134
+ }
135
+ const request = {
136
+ ...contact.dbo,
137
+ type: contact.dbo.type,
138
+ status: 'active',
139
+ countryID: '--',
140
+ roles: ['contributor'],
141
+ spaceID: spaceRef.id,
142
+ };
143
+ this.$isSubmitting.set(true);
144
+ this.addMemberForm.disable();
145
+ this.memberService.createMember(request).subscribe({
146
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
147
+ next: (_member) => {
148
+ // console.log('member created:', member);
149
+ if (this.hasNavHistory) {
150
+ this.navController
151
+ .pop()
152
+ .catch(this.errorLogger.logErrorHandler('failed to navigate to prev page'));
153
+ }
154
+ else {
155
+ this.spaceNavService
156
+ .navigateBackToSpacePage(spaceRef, 'members')
157
+ .catch(this.errorLogger.logErrorHandler('failed to navigate back to members page'));
158
+ }
159
+ },
160
+ error: (err) => {
161
+ this.errorLogger.logError(err, 'Failed to create a new member');
162
+ this.addMemberForm.enable();
163
+ setTimeout(() => {
164
+ this.$isSubmitting.set(false);
165
+ }, 1000);
166
+ },
167
+ });
168
+ // this.startCommuneReadwriteTx([MemberKind], (tx, communeDto, userDto) =>
169
+ // this.membersService.addCommuneItem(
170
+ // {
171
+ // ...memberDto,
172
+ // communeId: communeDto.id,
173
+ // },
174
+ // tx,
175
+ // ))
176
+ // .subscribe({
177
+ // next: member => {
178
+ // console.log('New member ID:', member.id);
179
+ // setTimeout(
180
+ // () => {
181
+ // this.navigateRoot(
182
+ // 'member',
183
+ // { id: member.id },
184
+ // { memberDto: member },
185
+ // );
186
+ // },
187
+ // // tslint:disable-next-line:no-magic-numbers
188
+ // 100,
189
+ // );
190
+ // },
191
+ // error: err => {
192
+ // this.errorLogger.logError(err, 'Failed to create new member');
193
+ // },
194
+ // },
195
+ // );
196
+ }
197
+ onContactChanged(contact) {
198
+ // console.log('NewMemberFormComponent.onContactChanged()', contact);
199
+ this.setPersonRequirements(contact);
200
+ this.contactChange.emit(contact);
201
+ }
202
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NewMemberFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
203
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: NewMemberFormComponent, isStandalone: true, selector: "sneat-new-member-form", providers: [{ provide: ClassName, useValue: 'NewMemberFormComponent' }], viewQueries: [{ propertyName: "personFormComponent", first: true, predicate: PersonWizardComponent, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"addMemberForm\" (ngSubmit)=\"submit()\">\n <sneat-person-wizard\n [$space]=\"$spaceRef()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"onContactChanged($event)\"\n [displayAgeGroupValue]=\"true\"\n [disabled]=\"$isSubmitting()\"\n [requires]=\"personRequirements\"\n [$fields]=\"{ contactType: { hide: true } }\"\n />\n\n @if (addMemberForm.errors) {\n <ion-card>\n <ion-card-header color=\"danger\">\n <ion-card-title>Errors</ion-card-title>\n </ion-card-header>\n <ion-card-content> Errors: {{ addMemberForm.errors }}</ion-card-content>\n </ion-card>\n }\n\n <ion-card>\n <ion-grid>\n <ion-row>\n <ion-col size=\"5\">\n <!--\t\t\t\t\tpersonRequirements: {{personRequirements|json}}-->\n <!--\t\t\t\t\t$isContactReady: {{$isContactReady()}}-->\n <ion-button\n expand=\"full\"\n size=\"large\"\n (click)=\"submit()\"\n [disabled]=\"!$canSubmit()\"\n >\n @if ($isSubmitting()) {\n <ion-spinner\n name=\"lines-small\"\n slot=\"start\"\n class=\"ion-margin-end\"\n />\n }\n <ion-label>Add member</ion-label>\n </ion-button>\n </ion-col>\n <ion-col size=\"1\" style=\"text-align: center\">\n <p>or</p>\n </ion-col>\n @if (!$isSubmitting()) {\n <ion-col size=\"6\">\n <qrcode\n style=\"float: left\"\n [qrdata]=\"$qrData()\"\n [width]=\"140\"\n errorCorrectionLevel=\"M\"\n />\n <ion-card-header>\n <ion-card-title>Self-add</ion-card-title>\n <ion-card-subtitle>\n Ask the new member to scan this QR code and fill the form to\n join this space. Or send them this\n <a target=\"_blank\" [href]=\"$qrData()\">link</a>.\n </ion-card-subtitle>\n </ion-card-header>\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n </ion-card>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: PersonWizardComponent, selector: "sneat-person-wizard", inputs: ["requires", "disabled", "hideRelationship", "hidePetOption", "displayAgeGroupValue", "nameFields", "$fields"], outputs: ["isReadyToSubmitChange"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: QRCodeComponent, selector: "qrcode", inputs: ["allowEmptyString", "colorDark", "colorLight", "cssClass", "elementType", "errorCorrectionLevel", "imageSrc", "imageHeight", "imageWidth", "margin", "qrdata", "scale", "version", "width", "alt", "ariaLabel", "title"], outputs: ["qrCodeURL"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonRow, selector: "ion-row" }, { kind: "component", type: IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }], animations: [formNexInAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
204
+ }
205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NewMemberFormComponent, decorators: [{
206
+ type: Component,
207
+ args: [{ animations: [formNexInAnimation], imports: [
208
+ FormsModule,
209
+ ReactiveFormsModule,
210
+ PersonWizardComponent,
211
+ IonCard,
212
+ IonCardContent,
213
+ IonCardHeader,
214
+ IonCardTitle,
215
+ IonCardSubtitle,
216
+ QRCodeComponent,
217
+ IonButton,
218
+ IonSpinner,
219
+ IonLabel,
220
+ IonRow,
221
+ IonGrid,
222
+ IonCol,
223
+ ], providers: [{ provide: ClassName, useValue: 'NewMemberFormComponent' }], changeDetection: ChangeDetectionStrategy.OnPush, selector: 'sneat-new-member-form', template: "<form [formGroup]=\"addMemberForm\" (ngSubmit)=\"submit()\">\n <sneat-person-wizard\n [$space]=\"$spaceRef()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"onContactChanged($event)\"\n [displayAgeGroupValue]=\"true\"\n [disabled]=\"$isSubmitting()\"\n [requires]=\"personRequirements\"\n [$fields]=\"{ contactType: { hide: true } }\"\n />\n\n @if (addMemberForm.errors) {\n <ion-card>\n <ion-card-header color=\"danger\">\n <ion-card-title>Errors</ion-card-title>\n </ion-card-header>\n <ion-card-content> Errors: {{ addMemberForm.errors }}</ion-card-content>\n </ion-card>\n }\n\n <ion-card>\n <ion-grid>\n <ion-row>\n <ion-col size=\"5\">\n <!--\t\t\t\t\tpersonRequirements: {{personRequirements|json}}-->\n <!--\t\t\t\t\t$isContactReady: {{$isContactReady()}}-->\n <ion-button\n expand=\"full\"\n size=\"large\"\n (click)=\"submit()\"\n [disabled]=\"!$canSubmit()\"\n >\n @if ($isSubmitting()) {\n <ion-spinner\n name=\"lines-small\"\n slot=\"start\"\n class=\"ion-margin-end\"\n />\n }\n <ion-label>Add member</ion-label>\n </ion-button>\n </ion-col>\n <ion-col size=\"1\" style=\"text-align: center\">\n <p>or</p>\n </ion-col>\n @if (!$isSubmitting()) {\n <ion-col size=\"6\">\n <qrcode\n style=\"float: left\"\n [qrdata]=\"$qrData()\"\n [width]=\"140\"\n errorCorrectionLevel=\"M\"\n />\n <ion-card-header>\n <ion-card-title>Self-add</ion-card-title>\n <ion-card-subtitle>\n Ask the new member to scan this QR code and fill the form to\n join this space. Or send them this\n <a target=\"_blank\" [href]=\"$qrData()\">link</a>.\n </ion-card-subtitle>\n </ion-card-header>\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n </ion-card>\n</form>\n" }]
224
+ }], ctorParameters: () => [], propDecorators: { personFormComponent: [{
225
+ type: ViewChild,
226
+ args: [PersonWizardComponent, { static: false }]
227
+ }] } });
228
+
229
+ class NewMemberPageComponent extends SpacePageBaseComponent {
230
+ // @ViewChild('nameInput', { static: false }) nameInput?: IonInput;
231
+ onContactTypeChanged(event) {
232
+ this.$contact.update((contact) => ({
233
+ ...contact,
234
+ dbo: {
235
+ ...contact.dbo,
236
+ type: event.detail.value,
237
+ },
238
+ }));
239
+ }
240
+ $inviteType = signal('mass', ...(ngDevMode ? [{ debugName: "$inviteType" }] : /* istanbul ignore next */ []));
241
+ $contact = signal({
242
+ space: { id: '' },
243
+ dbo: {
244
+ type: 'person',
245
+ gender: 'unknown', // Undefined would indicate "loading" and gender form would be disabled.
246
+ roles: [RoleSpaceMember],
247
+ },
248
+ }, ...(ngDevMode ? [{ debugName: "$contact" }] : /* istanbul ignore next */ []));
249
+ $contactType = computed(() => this.$contact().dbo?.type, ...(ngDevMode ? [{ debugName: "$contactType" }] : /* istanbul ignore next */ []));
250
+ constructor() {
251
+ super();
252
+ this.$defaultBackUrlSpacePath.set('members');
253
+ const contactusSpaceContextService = new ContactusSpaceContextService(this.destroyed$, this.spaceIDChanged$);
254
+ effect(() => {
255
+ const space = this.$spaceRef();
256
+ this.$contact.update((contact) => ({
257
+ ...contact,
258
+ space: space || { id: '' },
259
+ }));
260
+ });
261
+ this.trackFirstSpaceTypeChanged();
262
+ this.route.queryParams.subscribe((params) => {
263
+ const group = params['group'];
264
+ const setContactTypeAndAgeGroup = (contact, contactType, ageGroup) => ({
265
+ ...contact,
266
+ dbo: {
267
+ ...contact.dbo,
268
+ type: contactType,
269
+ ageGroup,
270
+ },
271
+ });
272
+ switch (group) {
273
+ case 'adults':
274
+ this.$contact.update((contact) => setContactTypeAndAgeGroup(contact, 'person', 'adult'));
275
+ break;
276
+ case 'kids':
277
+ this.$contact.update((contact) => setContactTypeAndAgeGroup(contact, 'person', 'child'));
278
+ break;
279
+ case 'pets':
280
+ this.$contact.update((contact) => setContactTypeAndAgeGroup(contact, 'animal'));
281
+ break;
282
+ default:
283
+ this.$contact.update((contact) => setContactTypeAndAgeGroup(contact, 'person'));
284
+ break;
285
+ }
286
+ const roles = params['roles'] || '';
287
+ if (roles) {
288
+ this.$contact.update((contact) => ({
289
+ ...contact,
290
+ dbo: {
291
+ ...contact.dbo,
292
+ roles: roles.split(',').map((s) => s.trim()),
293
+ },
294
+ }));
295
+ }
296
+ });
297
+ contactusSpaceContextService.contactusSpaceContext$
298
+ .pipe(this.takeUntilDestroyed())
299
+ .subscribe({
300
+ next: (contactusTeam) => {
301
+ this.contactusSpace = contactusTeam;
302
+ },
303
+ });
304
+ }
305
+ contactusSpace;
306
+ trackFirstSpaceTypeChanged = () => {
307
+ try {
308
+ this.spaceTypeChanged$
309
+ .pipe(takeUntil(this.destroyed$), filter((v) => !!v), first())
310
+ .subscribe({
311
+ next: (spaceType) => {
312
+ console.log('NewMemberPageComponent: spaceTypeChanged$ =>', spaceType);
313
+ if (spaceType === 'family' && this.$inviteType() === 'mass') {
314
+ this.$inviteType.set('personal');
315
+ }
316
+ },
317
+ error: this.logErrorHandler('failed to process space type changes'),
318
+ });
319
+ }
320
+ catch (e) {
321
+ this.logError(e, 'failed to subscribe for first space type change');
322
+ }
323
+ };
324
+ onTabChanged(event) {
325
+ this.$inviteType.set(event.detail.value);
326
+ }
327
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NewMemberPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
328
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: NewMemberPageComponent, isStandalone: true, selector: "sneat-new-member-page", providers: [{ provide: ClassName, useValue: 'NewMemberPageComponent' }], usesInheritance: true, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\" class=\"with-back-button\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>\n @if (space.brief || space.type) {\n @if ($contact().dbo.type === \"animal\") {\n New pet\n } @else {\n @switch ($contact().dbo.ageGroup) {\n @case (\"child\") {\n New child\n }\n @case (\"adult\") {\n New adult\n }\n @default {\n New member\n }\n }\n }\n &#64; {{ $space().brief?.title || space.type }}\n } @else {\n New member\n }\n </ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-segment\n [value]=\"$contactType()\"\n (ionChange)=\"onContactTypeChanged($event)\"\n>\n <ion-segment-button value=\"person\">Person</ion-segment-button>\n <ion-segment-button value=\"animal\">Pet</ion-segment-button>\n</ion-segment>\n\n<ion-content class=\"cardy\">\n @switch ($contactType()) {\n @case (\"person\") {\n @if (space.id && space.type !== \"family\") {\n <ion-segment [value]=\"$inviteType()\" (ionChange)=\"onTabChanged($event)\">\n <ion-segment-button value=\"mass\">\n Mass invite [{{ space.id }} - {{ space.type }}]\n </ion-segment-button>\n <ion-segment-button value=\"personal\"\n >Personal invite</ion-segment-button\n >\n </ion-segment>\n }\n\n @switch ($inviteType()) {\n @case (\"personal\") {\n <sneat-new-member-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"$contact.set($event)\"\n />\n }\n @case (\"mass\") {\n <ion-card>\n <ion-card-content>\n <sneat-invite-links [contactusSpace]=\"contactusSpace\" />\n\n <p>\n <b>Or</b> you can send\n <a\n href=\"\"\n (click)=\"$inviteType.set('personal'); $event.preventDefault()\"\n >personal invite</a\n >\n by email.\n </p>\n </ion-card-content>\n </ion-card>\n }\n }\n }\n @case (\"animal\") {\n <sneat-new-pet-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"$contact.set($event)\"\n />\n }\n }\n</ion-content>\n", dependencies: [{ kind: "ngmodule", type: ContactusServicesModule }, { kind: "component", type: NewMemberFormComponent, selector: "sneat-new-member-form" }, { kind: "component", type: InviteLinksComponent, selector: "sneat-invite-links", inputs: ["contactusSpace"] }, { kind: "ngmodule", type: SpaceServiceModule }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonSegment, selector: "ion-segment", inputs: ["color", "disabled", "mode", "scrollable", "selectOnFocus", "swipeGesture", "value"] }, { kind: "component", type: IonSegmentButton, selector: "ion-segment-button", inputs: ["contentId", "disabled", "layout", "mode", "type", "value"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonBackButton, selector: "ion-back-button" }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: NewPetFormComponent, selector: "sneat-new-pet-form" }] });
329
+ }
330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NewMemberPageComponent, decorators: [{
331
+ type: Component,
332
+ args: [{ imports: [
333
+ ContactusServicesModule,
334
+ NewMemberFormComponent,
335
+ InviteLinksComponent,
336
+ SpaceServiceModule,
337
+ IonContent,
338
+ IonSegment,
339
+ IonSegmentButton,
340
+ IonHeader,
341
+ IonToolbar,
342
+ IonButtons,
343
+ IonBackButton,
344
+ IonTitle,
345
+ IonCard,
346
+ IonCardContent,
347
+ NewPetFormComponent,
348
+ ], providers: [{ provide: ClassName, useValue: 'NewMemberPageComponent' }], selector: 'sneat-new-member-page', template: "<ion-header>\n <ion-toolbar color=\"light\" class=\"with-back-button\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>\n @if (space.brief || space.type) {\n @if ($contact().dbo.type === \"animal\") {\n New pet\n } @else {\n @switch ($contact().dbo.ageGroup) {\n @case (\"child\") {\n New child\n }\n @case (\"adult\") {\n New adult\n }\n @default {\n New member\n }\n }\n }\n &#64; {{ $space().brief?.title || space.type }}\n } @else {\n New member\n }\n </ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-segment\n [value]=\"$contactType()\"\n (ionChange)=\"onContactTypeChanged($event)\"\n>\n <ion-segment-button value=\"person\">Person</ion-segment-button>\n <ion-segment-button value=\"animal\">Pet</ion-segment-button>\n</ion-segment>\n\n<ion-content class=\"cardy\">\n @switch ($contactType()) {\n @case (\"person\") {\n @if (space.id && space.type !== \"family\") {\n <ion-segment [value]=\"$inviteType()\" (ionChange)=\"onTabChanged($event)\">\n <ion-segment-button value=\"mass\">\n Mass invite [{{ space.id }} - {{ space.type }}]\n </ion-segment-button>\n <ion-segment-button value=\"personal\"\n >Personal invite</ion-segment-button\n >\n </ion-segment>\n }\n\n @switch ($inviteType()) {\n @case (\"personal\") {\n <sneat-new-member-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"$contact.set($event)\"\n />\n }\n @case (\"mass\") {\n <ion-card>\n <ion-card-content>\n <sneat-invite-links [contactusSpace]=\"contactusSpace\" />\n\n <p>\n <b>Or</b> you can send\n <a\n href=\"\"\n (click)=\"$inviteType.set('personal'); $event.preventDefault()\"\n >personal invite</a\n >\n by email.\n </p>\n </ion-card-content>\n </ion-card>\n }\n }\n }\n @case (\"animal\") {\n <sneat-new-pet-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"$contact.set($event)\"\n />\n }\n }\n</ion-content>\n" }]
349
+ }], ctorParameters: () => [] });
350
+
351
+ export { NewMemberPageComponent };
352
+ //# sourceMappingURL=sneat-extension-contactus-index-DVC9hDgV.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sneat-extension-contactus-index-DVC9hDgV.mjs","sources":["../../../../../../libs/extensions/contactus/runtime/src/lib/members/pages/new-member/new-member-form.component.ts","../../../../../../libs/extensions/contactus/runtime/src/lib/members/pages/new-member/new-member-form.component.html","../../../../../../libs/extensions/contactus/runtime/src/lib/members/pages/new-member/new-member-page.component.ts","../../../../../../libs/extensions/contactus/runtime/src/lib/members/pages/new-member/new-member-page.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n OnChanges,\n signal,\n SimpleChanges,\n ViewChild,\n} from '@angular/core';\nimport {\n FormsModule,\n ReactiveFormsModule,\n UntypedFormGroup,\n} from '@angular/forms';\nimport {\n IonButton,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardSubtitle,\n IonCardTitle,\n IonCol,\n IonGrid,\n IonLabel,\n IonRow,\n IonSpinner,\n NavController,\n} from '@ionic/angular/standalone';\nimport { namesToUrlParams } from '@sneat/auth-models';\nimport { MemberService } from '../../../services';\nimport { PersonWizardComponent } from '@sneat/extension-contactus-ui';\nimport { formNexInAnimation } from '@sneat/core';\nimport { personNames } from '@sneat/auth-ui';\nimport { RoutingState } from '@sneat/core';\nimport {\n IContactusSpaceDboAndID,\n ICreateSpaceMemberRequest,\n IPersonRequirements,\n isRelatedPersonReady,\n MemberContactType,\n NewContactBaseDboAndSpaceRef,\n} from '@sneat/extension-contactus-contract';\nimport { zipMapBriefsWithIDs } from '@sneat/space-models';\nimport { QRCodeComponent } from 'angularx-qrcode';\nimport { WithNewContactInput } from '@sneat/extension-contactus-ui';\nimport { ClassName } from '@sneat/ui';\n\n@Component({\n animations: [formNexInAnimation],\n imports: [\n FormsModule,\n ReactiveFormsModule,\n PersonWizardComponent,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonCardSubtitle,\n QRCodeComponent,\n IonButton,\n IonSpinner,\n IonLabel,\n IonRow,\n IonGrid,\n IonCol,\n ],\n providers: [{ provide: ClassName, useValue: 'NewMemberFormComponent' }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'sneat-new-member-form',\n templateUrl: 'new-member-form.component.html',\n})\nexport class NewMemberFormComponent\n extends WithNewContactInput\n implements OnChanges\n{\n public personRequirements: IPersonRequirements = {\n ageGroup: { required: true },\n gender: { required: true },\n };\n\n private readonly navController = inject(NavController);\n\n private readonly hasNavHistory: boolean;\n protected readonly $isSubmitting = signal(false);\n\n protected readonly $canSubmit = computed(\n () =>\n this.$spaceRef().id &&\n !this.$isSubmitting() &&\n this.$isContactReady() &&\n !this.addMemberForm.disabled && //TODO(check) Could be a problem with Push detection strategy?\n this.addMemberForm.valid,\n );\n\n protected readonly $qrData = computed(() => {\n const contact = this.$contact();\n let url = `https://sneat.app/pwa/join?family=${contact.space.id}`;\n const { gender, ageGroup } = contact.dbo;\n if (\n gender &&\n gender !== 'unknown' &&\n gender !== 'undisclosed' &&\n gender !== 'other'\n ) {\n url += '&gender=' + gender;\n }\n if (ageGroup) {\n url += '&ageGroup=' + ageGroup;\n }\n url += namesToUrlParams(contact.dbo.names);\n url += '&utm_source=sneat.app&utm_medium=qr_code&utm_campaign=new_member';\n return url;\n });\n\n protected contactusSpace?: IContactusSpaceDboAndID;\n\n protected readonly $isContactReady = computed(() => {\n const contact = this.$contact();\n return (\n contact && isRelatedPersonReady(contact.dbo, this.personRequirements)\n );\n });\n\n @ViewChild(PersonWizardComponent, { static: false })\n personFormComponent?: PersonWizardComponent;\n // @ViewChild('emailInput', { static: false }) emailInput?: IonInput;\n // @ViewChild('genderFirstInput', { static: false }) genderFirstInput?: IonRadio;\n\n // public get isPersonFormReady(): boolean {\n // \treturn isRelatedPersonNotReady(this.member, this.personRequirements);\n // }\n //\n // public readonly setFocusToInput = createSetFocusToInput(\n // \tthis.params.errorLogger,\n // );\n\n // public readonly memberType = new FormControl<TeamMemberType>('member', [\n // \tValidators.required,\n // ]);\n\n public addMemberForm = new UntypedFormGroup({\n // email: this.email,\n // phone: this.phone,\n // ageGroup: this.ageGroup,\n // relationship: this.relationship,\n });\n\n private readonly memberService = inject(MemberService);\n\n public constructor() {\n super();\n const routingState = inject(RoutingState);\n this.hasNavHistory = routingState.hasHistory();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['$space']) {\n this.setPersonRequirements(this.$contact());\n }\n }\n\n private setPersonRequirements(contact: NewContactBaseDboAndSpaceRef): void {\n const spaceRef = this.$spaceRef();\n this.personRequirements = {\n // TODO: Should we move it inside person form wizard?\n ...this.personRequirements,\n ageGroup:\n spaceRef.type === 'family' && contact.dbo.type !== 'animal'\n ? { required: true }\n : { hide: true },\n roles:\n spaceRef.type === 'family' && contact.dbo.type !== 'animal'\n ? { hide: true }\n : { required: true },\n relatedAs:\n spaceRef.type === 'family' && contact.dbo.type !== 'animal'\n ? { required: true }\n : { hide: true },\n };\n }\n\n submit(): void {\n // if (!this.hasNames) {\n // \talert('Please enter first or last or full name of the new member');\n // \tif (!this.firstName.value && !this.lastName.value) {\n // \t\tthis.setFocusToInput(this.firstNameInput);\n // \t} else {\n // \t\tthis.setFocusToInput(this.fullNameInput);\n // \t}\n // \treturn;\n // }\n if (!this.personFormComponent) {\n throw '!this.personFormComponent';\n }\n const spaceRef = this.$spaceRef();\n const contact = this.$contact();\n if (!spaceRef?.id) {\n this.errorLogger.logError(\n 'not able to add new member without space context',\n );\n return;\n }\n if (!contact) {\n this.errorLogger.logError('member field is undefined');\n return;\n }\n if (this.personRequirements.ageGroup?.required && !contact.dbo.ageGroup) {\n throw new Error('Age group is a required field');\n }\n if (this.personRequirements.gender?.required && !contact.dbo.gender) {\n throw new Error('Gender is a required field');\n }\n const displayName = personNames(contact.dbo.names);\n const duplicateMember = zipMapBriefsWithIDs(\n this.contactusSpace?.dbo?.contacts,\n )?.find((m) => personNames(m.brief.names) === displayName);\n if (duplicateMember) {\n alert('There is already a member with same name: ' + displayName);\n return;\n }\n\n const request: ICreateSpaceMemberRequest = {\n ...contact.dbo,\n type: contact.dbo.type as MemberContactType,\n status: 'active',\n countryID: '--',\n roles: ['contributor'],\n spaceID: spaceRef.id,\n };\n\n this.$isSubmitting.set(true);\n this.addMemberForm.disable();\n this.memberService.createMember(request).subscribe({\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n next: (_member) => {\n // console.log('member created:', member);\n if (this.hasNavHistory) {\n this.navController\n .pop()\n .catch(\n this.errorLogger.logErrorHandler(\n 'failed to navigate to prev page',\n ),\n );\n } else {\n this.spaceNavService\n .navigateBackToSpacePage(spaceRef, 'members')\n .catch(\n this.errorLogger.logErrorHandler(\n 'failed to navigate back to members page',\n ),\n );\n }\n },\n error: (err) => {\n this.errorLogger.logError(err, 'Failed to create a new member');\n this.addMemberForm.enable();\n setTimeout(() => {\n this.$isSubmitting.set(false);\n }, 1000);\n },\n });\n\n // this.startCommuneReadwriteTx([MemberKind], (tx, communeDto, userDto) =>\n // \tthis.membersService.addCommuneItem(\n // \t\t{\n // \t\t\t...memberDto,\n // \t\t\tcommuneId: communeDto.id,\n // \t\t},\n // \t\ttx,\n // \t))\n // \t.subscribe({\n // \t\t\tnext: member => {\n // \t\t\t\tconsole.log('New member ID:', member.id);\n // \t\t\t\tsetTimeout(\n // \t\t\t\t\t() => {\n // \t\t\t\t\t\tthis.navigateRoot(\n // \t\t\t\t\t\t\t'member',\n // \t\t\t\t\t\t\t{ id: member.id },\n // \t\t\t\t\t\t\t{ memberDto: member },\n // \t\t\t\t\t\t);\n // \t\t\t\t\t},\n // \t\t\t\t\t// tslint:disable-next-line:no-magic-numbers\n // \t\t\t\t\t100,\n // \t\t\t\t);\n // \t\t\t},\n // \t\t\terror: err => {\n // \t\t\t\tthis.errorLogger.logError(err, 'Failed to create new member');\n // \t\t\t},\n // \t\t},\n // \t);\n }\n\n onContactChanged(contact: NewContactBaseDboAndSpaceRef): void {\n // console.log('NewMemberFormComponent.onContactChanged()', contact);\n this.setPersonRequirements(contact);\n this.contactChange.emit(contact);\n }\n}\n","<form [formGroup]=\"addMemberForm\" (ngSubmit)=\"submit()\">\n <sneat-person-wizard\n [$space]=\"$spaceRef()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"onContactChanged($event)\"\n [displayAgeGroupValue]=\"true\"\n [disabled]=\"$isSubmitting()\"\n [requires]=\"personRequirements\"\n [$fields]=\"{ contactType: { hide: true } }\"\n />\n\n @if (addMemberForm.errors) {\n <ion-card>\n <ion-card-header color=\"danger\">\n <ion-card-title>Errors</ion-card-title>\n </ion-card-header>\n <ion-card-content> Errors: {{ addMemberForm.errors }}</ion-card-content>\n </ion-card>\n }\n\n <ion-card>\n <ion-grid>\n <ion-row>\n <ion-col size=\"5\">\n <!--\t\t\t\t\tpersonRequirements: {{personRequirements|json}}-->\n <!--\t\t\t\t\t$isContactReady: {{$isContactReady()}}-->\n <ion-button\n expand=\"full\"\n size=\"large\"\n (click)=\"submit()\"\n [disabled]=\"!$canSubmit()\"\n >\n @if ($isSubmitting()) {\n <ion-spinner\n name=\"lines-small\"\n slot=\"start\"\n class=\"ion-margin-end\"\n />\n }\n <ion-label>Add member</ion-label>\n </ion-button>\n </ion-col>\n <ion-col size=\"1\" style=\"text-align: center\">\n <p>or</p>\n </ion-col>\n @if (!$isSubmitting()) {\n <ion-col size=\"6\">\n <qrcode\n style=\"float: left\"\n [qrdata]=\"$qrData()\"\n [width]=\"140\"\n errorCorrectionLevel=\"M\"\n />\n <ion-card-header>\n <ion-card-title>Self-add</ion-card-title>\n <ion-card-subtitle>\n Ask the new member to scan this QR code and fill the form to\n join this space. Or send them this\n <a target=\"_blank\" [href]=\"$qrData()\">link</a>.\n </ion-card-subtitle>\n </ion-card-header>\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n </ion-card>\n</form>\n","import { Component, computed, effect, signal } from '@angular/core';\nimport {\n IonBackButton,\n IonButtons,\n IonCard,\n IonCardContent,\n IonContent,\n IonHeader,\n IonSegment,\n IonSegmentButton,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular/standalone';\nimport {\n ContactusServicesModule,\n ContactusSpaceContextService,\n} from '../../../services';\nimport {\n InviteLinksComponent,\n NewPetFormComponent,\n} from '@sneat/extension-contactus-ui';\nimport {\n ContactType,\n IContactusSpaceDboAndID,\n NewContactBaseDboAndSpaceRef,\n RoleSpaceMember,\n} from '@sneat/extension-contactus-contract';\nimport { AgeGroupID } from '@sneat/core';\nimport { SpacePageBaseComponent } from '@sneat/space-components';\nimport { SpaceServiceModule } from '@sneat/space-services';\nimport { filter, first, takeUntil } from 'rxjs';\nimport { NewMemberFormComponent } from './new-member-form.component';\nimport { ClassName } from '@sneat/ui';\n\ntype InviteType = 'personal' | 'mass';\n\n@Component({\n imports: [\n ContactusServicesModule,\n NewMemberFormComponent,\n InviteLinksComponent,\n SpaceServiceModule,\n IonContent,\n IonSegment,\n IonSegmentButton,\n IonHeader,\n IonToolbar,\n IonButtons,\n IonBackButton,\n IonTitle,\n IonCard,\n IonCardContent,\n NewPetFormComponent,\n ],\n providers: [{ provide: ClassName, useValue: 'NewMemberPageComponent' }],\n selector: 'sneat-new-member-page',\n templateUrl: './new-member-page.component.html',\n})\nexport class NewMemberPageComponent extends SpacePageBaseComponent {\n // @ViewChild('nameInput', { static: false }) nameInput?: IonInput;\n\n protected onContactTypeChanged(event: CustomEvent): void {\n this.$contact.update((contact) => ({\n ...contact,\n dbo: {\n ...contact.dbo,\n type: event.detail.value as ContactType,\n },\n }));\n }\n\n protected readonly $inviteType = signal<InviteType>('mass');\n\n protected readonly $contact = signal<NewContactBaseDboAndSpaceRef>({\n space: { id: '' },\n dbo: {\n type: 'person',\n gender: 'unknown', // Undefined would indicate \"loading\" and gender form would be disabled.\n roles: [RoleSpaceMember],\n },\n });\n\n protected readonly $contactType = computed(() => this.$contact().dbo?.type);\n\n public constructor() {\n super();\n this.$defaultBackUrlSpacePath.set('members');\n const contactusSpaceContextService = new ContactusSpaceContextService(\n this.destroyed$,\n this.spaceIDChanged$,\n );\n effect(() => {\n const space = this.$spaceRef();\n this.$contact.update((contact) => ({\n ...contact,\n space: space || { id: '' },\n }));\n });\n this.trackFirstSpaceTypeChanged();\n this.route.queryParams.subscribe((params) => {\n const group = params['group'];\n const setContactTypeAndAgeGroup = (\n contact: NewContactBaseDboAndSpaceRef,\n contactType: ContactType,\n ageGroup?: AgeGroupID,\n ) => ({\n ...contact,\n dbo: {\n ...contact.dbo,\n type: contactType,\n ageGroup,\n },\n });\n switch (group) {\n case 'adults':\n this.$contact.update((contact) =>\n setContactTypeAndAgeGroup(contact, 'person', 'adult'),\n );\n break;\n case 'kids':\n this.$contact.update((contact) =>\n setContactTypeAndAgeGroup(contact, 'person', 'child'),\n );\n break;\n case 'pets':\n this.$contact.update((contact) =>\n setContactTypeAndAgeGroup(contact, 'animal'),\n );\n break;\n default:\n this.$contact.update((contact) =>\n setContactTypeAndAgeGroup(contact, 'person'),\n );\n break;\n }\n const roles = params['roles'] || '';\n if (roles) {\n this.$contact.update((contact) => ({\n ...contact,\n dbo: {\n ...contact.dbo,\n roles: roles.split(',').map((s: string) => s.trim()),\n },\n }));\n }\n });\n\n contactusSpaceContextService.contactusSpaceContext$\n .pipe(this.takeUntilDestroyed())\n .subscribe({\n next: (contactusTeam) => {\n this.contactusSpace = contactusTeam;\n },\n });\n }\n\n protected contactusSpace?: IContactusSpaceDboAndID;\n\n private readonly trackFirstSpaceTypeChanged = (): void => {\n try {\n this.spaceTypeChanged$\n .pipe(\n takeUntil(this.destroyed$),\n filter((v) => !!v),\n first(),\n )\n .subscribe({\n next: (spaceType) => {\n console.log(\n 'NewMemberPageComponent: spaceTypeChanged$ =>',\n spaceType,\n );\n if (spaceType === 'family' && this.$inviteType() === 'mass') {\n this.$inviteType.set('personal');\n }\n },\n error: this.logErrorHandler('failed to process space type changes'),\n });\n } catch (e) {\n this.logError(e, 'failed to subscribe for first space type change');\n }\n };\n\n protected onTabChanged(event: CustomEvent): void {\n this.$inviteType.set(event.detail.value as InviteType);\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\" class=\"with-back-button\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>\n @if (space.brief || space.type) {\n @if ($contact().dbo.type === \"animal\") {\n New pet\n } @else {\n @switch ($contact().dbo.ageGroup) {\n @case (\"child\") {\n New child\n }\n @case (\"adult\") {\n New adult\n }\n @default {\n New member\n }\n }\n }\n &#64; {{ $space().brief?.title || space.type }}\n } @else {\n New member\n }\n </ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-segment\n [value]=\"$contactType()\"\n (ionChange)=\"onContactTypeChanged($event)\"\n>\n <ion-segment-button value=\"person\">Person</ion-segment-button>\n <ion-segment-button value=\"animal\">Pet</ion-segment-button>\n</ion-segment>\n\n<ion-content class=\"cardy\">\n @switch ($contactType()) {\n @case (\"person\") {\n @if (space.id && space.type !== \"family\") {\n <ion-segment [value]=\"$inviteType()\" (ionChange)=\"onTabChanged($event)\">\n <ion-segment-button value=\"mass\">\n Mass invite [{{ space.id }} - {{ space.type }}]\n </ion-segment-button>\n <ion-segment-button value=\"personal\"\n >Personal invite</ion-segment-button\n >\n </ion-segment>\n }\n\n @switch ($inviteType()) {\n @case (\"personal\") {\n <sneat-new-member-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"$contact.set($event)\"\n />\n }\n @case (\"mass\") {\n <ion-card>\n <ion-card-content>\n <sneat-invite-links [contactusSpace]=\"contactusSpace\" />\n\n <p>\n <b>Or</b> you can send\n <a\n href=\"\"\n (click)=\"$inviteType.set('personal'); $event.preventDefault()\"\n >personal invite</a\n >\n by email.\n </p>\n </ion-card-content>\n </ion-card>\n }\n }\n }\n @case (\"animal\") {\n <sneat-new-pet-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n (contactChange)=\"$contact.set($event)\"\n />\n }\n }\n</ion-content>\n"],"names":[],"mappings":"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"}