From 70817ad3a0796010e08d2e2456afd0d4fb737786 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 22 Jul 2019 00:44:35 -0600 Subject: [PATCH] All Fields and service for missionary form --- Client/src/app/app-routing.module.ts | 5 + Client/src/app/app.module.ts | 11 +- .../missionary-form-page.component.css | 58 ++++ .../missionary-form-page.component.html | 323 ++++++++++++++++++ .../missionary-form-page.component.spec.ts | 25 ++ .../missionary-form-page.component.ts | 178 ++++++++++ Client/src/app/constants/urls.ts | 1 + .../services/missionary-support-service.ts | 41 +++ 8 files changed, 639 insertions(+), 3 deletions(-) create mode 100644 Client/src/app/components/missionary-form-page/missionary-form-page.component.css create mode 100644 Client/src/app/components/missionary-form-page/missionary-form-page.component.html create mode 100644 Client/src/app/components/missionary-form-page/missionary-form-page.component.spec.ts create mode 100644 Client/src/app/components/missionary-form-page/missionary-form-page.component.ts create mode 100644 Client/src/app/services/missionary-support-service.ts diff --git a/Client/src/app/app-routing.module.ts b/Client/src/app/app-routing.module.ts index a290387..d66b3b6 100644 --- a/Client/src/app/app-routing.module.ts +++ b/Client/src/app/app-routing.module.ts @@ -13,6 +13,7 @@ import { SalvationPageComponent } from './components/salvation-page/salvation-pa import { CampPageComponent } from './components/camp-page/camp-page.component'; import { MembersPageComponent } from './components/members-page/members-page.component'; import { AddTransactionPageComponent } from './components/add-transaction-page/add-transaction-page.component'; +import { MissionaryFormPageComponent } from './components/missionary-form-page/missionary-form-page.component'; const routes = [ @@ -36,6 +37,10 @@ const routes = path: 'contact', component: ContactPageComponent }, + { + path: 'missionary', + component: MissionaryFormPageComponent + }, { path: 'sermons', component: SermonsComponent diff --git a/Client/src/app/app.module.ts b/Client/src/app/app.module.ts index 81a4439..7656a0b 100644 --- a/Client/src/app/app.module.ts +++ b/Client/src/app/app.module.ts @@ -15,6 +15,7 @@ import { MatButtonModule, MatDialogModule, MatSelectModule, MatOptionModule, + MatRadioModule, MatAutocompleteModule} from '@angular/material'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import 'hammerjs'; @@ -69,6 +70,8 @@ import { UserService } from './services/user.service'; import { TransactionService } from './services/transaction.service'; import { AddTransactionPageComponent } from './components/add-transaction-page/add-transaction-page.component'; import { AddTransactionPopupComponent } from './components/add-transaction-page/add-transaction-popup/add-transaction-popup.component'; +import { MissionaryFormPageComponent } from './components/missionary-form-page/missionary-form-page.component'; +import { MissionarySupportService } from './services/missionary-support-service'; @@ -113,7 +116,8 @@ import { AddTransactionPopupComponent } from './components/add-transaction-page/ MembersPageComponent, AddUserPopupComponent, AddTransactionPageComponent, - AddTransactionPopupComponent + AddTransactionPopupComponent, + MissionaryFormPageComponent ], imports: [ BrowserModule, @@ -130,9 +134,10 @@ import { AddTransactionPopupComponent } from './components/add-transaction-page/ MatSliderModule, MatSnackBarModule, MatDialogModule, - MatAutocompleteModule + MatAutocompleteModule, + MatRadioModule ], - providers: [LoginService,UserService,GoogleAnalyticsService,SermonService,TransactionService,EventService,EmailService,WindowRefService], + providers: [LoginService,UserService,GoogleAnalyticsService,SermonService,TransactionService,EventService,EmailService,MissionarySupportService,WindowRefService], entryComponents: [AddSermonPopupComponent, LoginPopupComponent, OkPopupComponent, diff --git a/Client/src/app/components/missionary-form-page/missionary-form-page.component.css b/Client/src/app/components/missionary-form-page/missionary-form-page.component.css new file mode 100644 index 0000000..e1ae33c --- /dev/null +++ b/Client/src/app/components/missionary-form-page/missionary-form-page.component.css @@ -0,0 +1,58 @@ +.w-50 { + width: 50%; +} + +.w-100 { + width: 100%; +} + +.section-header{ + font-size: 1.2em; + font-weight: bold; + border-bottom: 1px solid gray; + margin-bottom: 10px; +} + +.error { + color: red; +} + +mat-label { + font-weight: bold; + overflow-wrap: break-word; +} + +label { + display: flex; + flex-direction: column; + font-size: 1.15rem; + margin-top: 35px; + color: black; + font-weight: 400; + font-family: Arial, Helvetica, sans-serif +} + +ol > li { + margin-left: 20px; +} + +mat-label { + font-size: 1.15rem; + color: black; + font-weight: 400; +} + +label.sub { + margin-top: 0px; + font-size: .85rem; +} + +mat-radio-button { + display: flex; + flex-direction: column; + margin: 15px 0; +} + +.hidden { + display: none; +} \ No newline at end of file diff --git a/Client/src/app/components/missionary-form-page/missionary-form-page.component.html b/Client/src/app/components/missionary-form-page/missionary-form-page.component.html new file mode 100644 index 0000000..3e9f367 --- /dev/null +++ b/Client/src/app/components/missionary-form-page/missionary-form-page.component.html @@ -0,0 +1,323 @@ + + +
+

+ Old Fashion Baptist Church Missionary Questionnaire +

+

+ I hate questionnaires! I've been there. I understand that deputation itself is tough enough already without some pastor probing into all kinds of areas! Then there is the fact that so many fundamental pastors themselves disagree in so many areas! + Now that I’ve said what you may have already been thinking, let me also say that I am continually amazed that every church doesn’t use a questionnaire to vet their missionaries. The truth is, we take seriously the fact that you are being considered for support by our church and feel that we can’t truly get to know you unless we ask some simple questions. +

+ You must understand that anyone whom we consider as a missionary for our Church has certain doctrinal beliefs which are assumed by us or else we would not be sending them a questionnaire. We also realize that good men will differ on some things and will make allowances accordingly. Also, because we have one questionnaire for all candidates, many of the things that are asked would be unnecessary if it were not being sent to everyone. We hope you understand that. In order for a missionary to be considered, we request that every question be answered. +

+ Thank you for your time and understanding. The questions are not meant in any way to be “trick” questions. +

+ God bless you! +

+ Pastor Derek Loewen +

+

+
+ + Name + + + + Wifes Name + + + + Home Phone + + + + Cell Phone + + + + Field Phone + + + + Number of Children + + +
+ +
    +
  1. +
    + + Childs Name + + +
    +
  2. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Attend a Christian School + Attend a Public School + Home School + Other + + + + Yes + No + + + + + Yes + No + + + + Yes + No + + + + Yes + No + + + + Yes + No + + + + Yes + No + + + + Rarely + Often + On Sports Activities + Never + + + + Rarely + Often + On Sports Activities + Never + + + + Yes + No + + + + + + + + + + + + Always + Sometimes + Rarely + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{form.get('collegeRecomendations').errors?.minColleges}} +
+
    +
  1. +
    + + Name + + + + City + + + + State + + +
    +
    + {{college.errors?.college}} +
    +
  2. +
+ + + + + + + Yes + No + + + + Yes + No + + + + Yes + No + + + + Yes + No + + + + + + + + + + + + Yes + No + + + + + + + + Yes + No + + + + Yes + No + + + + + + + + + Yes + No + + + + Yes + No + + + + + + + + + + + + + + + +
+
+ +
\ No newline at end of file diff --git a/Client/src/app/components/missionary-form-page/missionary-form-page.component.spec.ts b/Client/src/app/components/missionary-form-page/missionary-form-page.component.spec.ts new file mode 100644 index 0000000..52e3b3e --- /dev/null +++ b/Client/src/app/components/missionary-form-page/missionary-form-page.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MissionaryFormPageComponent } from './missionary-form-page.component'; + +describe('MissionaryFormPageComponent', () => { + let component: MissionaryFormPageComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MissionaryFormPageComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MissionaryFormPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/Client/src/app/components/missionary-form-page/missionary-form-page.component.ts b/Client/src/app/components/missionary-form-page/missionary-form-page.component.ts new file mode 100644 index 0000000..40fab33 --- /dev/null +++ b/Client/src/app/components/missionary-form-page/missionary-form-page.component.ts @@ -0,0 +1,178 @@ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormBuilder, Validators, FormArray, FormControl, ValidatorFn, ValidationErrors } from '@angular/forms'; +import { MissionarySupportService } from 'src/app/services/missionary-support-service'; +import { MatDialog, MatDialogConfig } from '@angular/material'; +import { OkPopupComponent } from '../popups/ok-popup/ok-popup.component'; + +@Component({ + selector: 'app-missionary-form-page', + templateUrl: './missionary-form-page.component.html', + styleUrls: ['./missionary-form-page.component.css'] +}) +export class MissionaryFormPageComponent implements OnInit { + + form: FormGroup; + submitButtonText: string = 'Submit'; + submitButtonDisabled: boolean = false; + errorMessages: string[] = []; + private maxNumberOfChildren: number = 30; + + constructor(private formBuilder: FormBuilder, private matDialog: MatDialog, private missionarySupportService: MissionarySupportService) { + this.setupForm(); + } + + ngOnInit() { + } + + setupForm() { + this.form = this.formBuilder.group({ + name: ['', [Validators.required]], + homePhone: [''], + cellPhone: [''], + fieldPhone: [''], + wifesName: [''], + numberOfChildren: ['', [Validators.required, Validators.max(this.maxNumberOfChildren)]], + children: this.formBuilder.array([]), + testimony: ['', Validators.required], + callToField: ['', Validators.required], + sendingChurch: ['', Validators.required], + fieldOfService: ['', Validators.required], //Country + City + plans: ['', Validators.required], + evaluationOfNationals: ['', Validators.required], + timeInCountry: ['', Validators.required], + correctWrongOfAnotherMissionary: ['', Validators.required], + financialStatementPrevYear: [undefined, Validators.required], + currentMonthlySupport: ['', Validators.required], + monthlySupportNeeded: ['', Validators.required], + restAndRelaxation: ['', Validators.required], + aloneOrTeam: ['', Validators.required], + childrenSchool: [undefined, Validators.required], + dance: ['', Validators.required], + worldlyMusic: [undefined, Validators.required], + movieTheaters: [undefined, Validators.required], + alcohol: [undefined, Validators.required], + smoking: [undefined, Validators.required], + maleHair: [undefined, Validators.required], + femaleSlacks: [undefined, Validators.required], + femaleShorts: [undefined, Validators.required], + femaleDressStandard: [undefined, Validators.required], + swimmingClothing: [undefined, Validators.required], + television: [undefined, Validators.required], + dailyBible: [undefined, Validators.required], + numberLedToChrist: ['', [Validators.required, Validators.min(0), Validators.max(10000)]], + numberWitnessedTo: ['', [Validators.required, Validators.min(0), Validators.max(10000)]], + numberWeeklyTracts: ['', [Validators.required, Validators.min(0), Validators.max(10000)]], + rateOfSuccess: ['', Validators.required], + predestination: ['', Validators.required], + fellowshipAssocation: ['', Validators.required], + collegeRecomendations: this.formBuilder.array([this.createCollegeRecommendation(),this.createCollegeRecommendation(),this.createCollegeRecommendation()], this.minCollegeValidator), + admittedWrong: ['', Validators.required], + divorced: [undefined, Validators.required], + groundsForRemarry: [undefined, Validators.required], + marryADivorcee: [undefined, Validators.required], + masonicLodge: [undefined, Validators.required], + bibleVersionsUsed: ['', Validators.required], + bibleVersionOpinion: ['', Validators.required], + contemporaryMusic: ['', Validators.required], + charasmaticism: ['', Validators.required], + tongues: [undefined, Validators.required], + repentanceNecessary: [undefined, Validators.required], + repentanceDefinition: [undefined, Validators.required], + fundamentalist: [undefined, Validators.required], + billsOnTime: [undefined, Validators.required], + lateBills: ['', Validators.required], + lateBillActionTaken: ['', Validators.required], + potentialHarvest: ['', Validators.required], + honeyPot: ['.', Validators.required] + }); + } + + collegeRecommendationFormArray(): FormArray { + return this.form.get('collegeRecommendations') as FormArray; + } + + addChildToForm() { + const children = this.form.get('children') as FormArray; + children.push(this.formBuilder.group({ + name: ['', Validators.required] + })); + } + + createCollegeRecommendation(): FormGroup { + return this.formBuilder.group({ + name: [''], + city: [''], + state: [''] + }, { validators: [this.collegeValidator]}); + } + + numberOfChildrenChange(number: Number) { + let num = +number; + num = num > this.maxNumberOfChildren ? this.maxNumberOfChildren : num; + const children = this.form.get('children') as FormArray; + while (children.length > num) { + children.removeAt(children.length - 1); + } + while (children.length < num) { + children.push(this.formBuilder.group({ + name: ['', Validators.required] + })); + } + } + + onSubmit(){ + this.errorMessages = []; + if (this.errorMessages.length > 0){ return; } + + this.submitButtonText = "Please Wait..."; + this.submitButtonDisabled = true; + this.missionarySupportService.create(this.form.value) + .subscribe( + success => {this.emailSuccess();}, + error => {this.emailError();}); + } + + private emailSuccess(){ + let opts = new MatDialogConfig; + opts.data = { title:'Email Sent','message':'Thank You! Your message has been sent.' }; + let popup = this.matDialog.open(OkPopupComponent,opts); + this.submitButtonText = "Submit"; + this.submitButtonDisabled = false; + popup.afterClosed().subscribe(()=>{ + this.submitButtonText = "Form Submitted" + }); + } + + private emailError(){ + console.error("error"); + let opts = new MatDialogConfig; + opts.data = { title:'Email Error','message':'Please make sure that you have entered a valid email address.' }; + let popup = this.matDialog.open(OkPopupComponent,opts); + this.submitButtonText = "Submit"; + this.submitButtonDisabled = false; + } + + private minCollegeValidator(control: FormArray): ValidationErrors | null { + const minRequired = 2; + let valid = 0; + for(let i = 0; i < control.controls.length; i++) { + const val = control.controls[i].value; + if (val.name && val.city && val.state && val.name.length > 0 && val.city.length > 0 && val.state.length > 0) { + valid++; + } + } + return valid >= minRequired ? null : { 'minColleges': 'Please enter at least two colleges.' }; + } + + private collegeValidator(control: FormGroup): ValidationErrors | null { + const name = control.value.name || ''; + const city = control.value.city || ''; + const state = control.value.state || ''; + if (name.length > 0 || city.length > 0 || state.length > 0) { + if (name.length === 0 || city.length === 0 || state.length === 0) { + return { 'college': 'Please enter name, city and state for each college.' }; + } + } + return null; + } +} diff --git a/Client/src/app/constants/urls.ts b/Client/src/app/constants/urls.ts index e9f3238..b514087 100644 --- a/Client/src/app/constants/urls.ts +++ b/Client/src/app/constants/urls.ts @@ -4,6 +4,7 @@ export const EVENTS_ADD_URL = environment.baseUrl + "/api2/events/a/"; export const EVENT_BY_ID = environment.baseUrl + "/api2/events/"; export const EVENTS_BY_PAGE_URL = environment.baseUrl + "/api2/events/page/"; export const EVENTS_DELETE_BY_ID_URL = environment.baseUrl + "/api2/events/a/"; +export const MISSIONARY_SUPPORT_CREATE_URL = environment.baseUrl + "/2/api/missionary"; export const SERMONS_BY_ID = environment.baseUrl + '/api2/sermons/'; export const SERMONS_BY_PAGE_URL = environment.baseUrl + '/api2/sermons/page/'; export const SERMONS_BY_SEARCH_URL = environment.baseUrl + '/api2/sermons/search'; diff --git a/Client/src/app/services/missionary-support-service.ts b/Client/src/app/services/missionary-support-service.ts new file mode 100644 index 0000000..b7ab132 --- /dev/null +++ b/Client/src/app/services/missionary-support-service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@angular/core'; +import { HttpClient, HttpErrorResponse } from '@angular/common/http'; + +import { throwError } from 'rxjs'; +import { catchError, tap } from 'rxjs/operators'; +import { MISSIONARY_SUPPORT_CREATE_URL } from '../constants/urls'; + +@Injectable() +export class MissionarySupportService { + + private options: {}; + + constructor(private httpClient: HttpClient){ + this.options = { + withCredentials: true + }; + } + + create(body: any) { + console.log(body); + return this.httpClient.post(MISSIONARY_SUPPORT_CREATE_URL, body, this.options) + .pipe(tap(res => console.log(res)), catchError(this.handleError)); + } + + private handleError(error: HttpErrorResponse) { + if (error.error instanceof ErrorEvent) { + // A client-side or network error occurred. Handle it accordingly. + console.error('An error occurred:', error.error.message); + } else { + // The backend returned an unsuccessful response code. + // The response body may contain clues as to what went wrong, + console.error( + `Backend returned code ${error.status}, ` + + `body was: ${error.error}`); + console.error(error); + } + // return an observable with a user-facing error message + return throwError((error && error.error && error.error.message) ? error.error.message : + 'Something bad happened; please try again later.'); + }; +}