Compare commits
257 Commits
Transactio
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
10b8212980 | |
|
|
0d13dcdb6d | |
|
|
6f45815e64 | |
|
|
9d5b6e5935 | |
|
|
01f8404805 | |
|
|
51579d2aee | |
|
|
dfeb90828f | |
|
|
8fd3c784e8 | |
|
|
13d5eca9ef | |
|
|
70146f0e73 | |
|
|
ca31b97b66 | |
|
|
ad23f0cfc7 | |
|
|
d5369eaaad | |
|
|
14777e9171 | |
|
|
c851c8a070 | |
|
|
9c98cb51ba | |
|
|
e66a014572 | |
|
|
ad9ec5e7c6 | |
|
|
96d7270332 | |
|
|
58bd3c28b0 | |
|
|
78e80c4b79 | |
|
|
53d9bd9cff | |
|
|
e8911b96f7 | |
|
|
78e36d8446 | |
|
|
e37304533e | |
|
|
d7d41931ee | |
|
|
2e0ec2b51d | |
|
|
a1e32936df | |
|
|
add85ebda7 | |
|
|
d898b2abae | |
|
|
b0002c2107 | |
|
|
b46bc5221e | |
|
|
f302b69c9a | |
|
|
da33858642 | |
|
|
98ca74cadf | |
|
|
8fd40c8dc6 | |
|
|
06c49558c4 | |
|
|
0f88898a67 | |
|
|
b8d4301429 | |
|
|
900029783f | |
|
|
2603f5208a | |
|
|
c420043ba3 | |
|
|
4373e27d40 | |
|
|
d0eaddf1d9 | |
|
|
89b21ddbd8 | |
|
|
61cff5f973 | |
|
|
3d3c0b9669 | |
|
|
d6178b2ca4 | |
|
|
c8879f964d | |
|
|
a038c449e7 | |
|
|
6701cf2faa | |
|
|
864b838b69 | |
|
|
3858ef2299 | |
|
|
cf0a57e8fd | |
|
|
38a1cdd486 | |
|
|
d7661b4649 | |
|
|
b319f3c109 | |
|
|
01766dc47f | |
|
|
afa4fe57ba | |
|
|
25a659d2cf | |
|
|
06b01f250e | |
|
|
6918ce605b | |
|
|
d8f295f1ba | |
|
|
bb341a5659 | |
|
|
6c3652f6ca | |
|
|
c97268133d | |
|
|
2f63d43c47 | |
|
|
2cd2685f91 | |
|
|
6f329251cc | |
|
|
a51644bf9f | |
|
|
e4f976ea2a | |
|
|
73bfb61f9b | |
|
|
f9e42fa69f | |
|
|
396f0cb7a1 | |
|
|
d82152684f | |
|
|
7d240c8fc9 | |
|
|
a344233780 | |
|
|
35c751e35f | |
|
|
48aa37354f | |
|
|
82886951f2 | |
|
|
f159d04987 | |
|
|
63b00fcd8a | |
|
|
51abacb9f2 | |
|
|
75415de5c7 | |
|
|
2797c504b4 | |
|
|
05fc3a220a | |
|
|
6fb5e5b27c | |
|
|
b05d63ebef | |
|
|
35f8a69c96 | |
|
|
f144faa870 | |
|
|
f3fbb80e19 | |
|
|
069c2d4f83 | |
|
|
d3e9d764e6 | |
|
|
0668feef04 | |
|
|
5b270b76a7 | |
|
|
d1c8e2d344 | |
|
|
867991eb68 | |
|
|
f13dc3a191 | |
|
|
34675f9ae1 | |
|
|
18ecf3337d | |
|
|
7a67e6eea9 | |
|
|
cd0bf8f317 | |
|
|
d91d4e5fa7 | |
|
|
0b267fd68f | |
|
|
0683120c9f | |
|
|
2b6f92dabb | |
|
|
bf81a30d8b | |
|
|
9c59ec76f0 | |
|
|
0631ad0f04 | |
|
|
5a88277d46 | |
|
|
2de90ed6d3 | |
|
|
f70bed9ebf | |
|
|
ecbbd7d2a5 | |
|
|
aadd145eef | |
|
|
8789391648 | |
|
|
8086288cda | |
|
|
bcc551e405 | |
|
|
c285b9cb95 | |
|
|
cd659e6249 | |
|
|
336152630b | |
|
|
47d94542b6 | |
|
|
96ad62751d | |
|
|
f031ea3c9b | |
|
|
baa8451918 | |
|
|
9777ecb0f0 | |
|
|
f89f673cdc | |
|
|
b758d2686e | |
|
|
22391f264e | |
|
|
f04b5c7895 | |
|
|
c629d2fc2a | |
|
|
c2a4c5f63e | |
|
|
cafa43e2e7 | |
|
|
cb1f61257e | |
|
|
00943dc324 | |
|
|
054c172f17 | |
|
|
d7053b0325 | |
|
|
2c1f48f189 | |
|
|
6b11cdd0ce | |
|
|
10561f523e | |
|
|
f4653c7098 | |
|
|
d91176713e | |
|
|
b57cec7136 | |
|
|
8b363f4cd6 | |
|
|
ef34bdd52a | |
|
|
d9c91881ef | |
|
|
5f4550998c | |
|
|
b7c98ee522 | |
|
|
cdd91b047c | |
|
|
3563df5791 | |
|
|
113979f09b | |
|
|
4bb0e1f39a | |
|
|
9f9d0fd384 | |
|
|
9e7f02e2be | |
|
|
6204f855f3 | |
|
|
d803501c31 | |
|
|
7dd6c656f2 | |
|
|
e2ff93c722 | |
|
|
dd3934ff9c | |
|
|
b056f0316d | |
|
|
93f6503bac | |
|
|
b3a73dd47b | |
|
|
ef5d4d8ee2 | |
|
|
c1b87f270a | |
|
|
af4b336327 | |
|
|
e6781aed41 | |
|
|
2e00913ac9 | |
|
|
08312e4e59 | |
|
|
8a58b35d13 | |
|
|
abf20f07de | |
|
|
2427623f26 | |
|
|
ea85959a14 | |
|
|
8b3fafd7f0 | |
|
|
e9d366612f | |
|
|
2585aa8625 | |
|
|
cadf1b1441 | |
|
|
e142786581 | |
|
|
c834ff4a75 | |
|
|
3970ccd93f | |
|
|
6394385986 | |
|
|
2a20f77c9e | |
|
|
93f3f02e73 | |
|
|
be06ad5c77 | |
|
|
eadbfe7fcc | |
|
|
d257f897b6 | |
|
|
e9a54ec5f5 | |
|
|
2a1bc133d2 | |
|
|
1acf91ae04 | |
|
|
ca663261be | |
|
|
875ae030f7 | |
|
|
c2d927788a | |
|
|
d4598d76c0 | |
|
|
1e422fa9d8 | |
|
|
cd64706b30 | |
|
|
39c6e1fd98 | |
|
|
6f26bb859d | |
|
|
a2edf88fb1 | |
|
|
ba8903c3ac | |
|
|
52caeed90f | |
|
|
c8ff77211d | |
|
|
4221f3f7db | |
|
|
e1d057bfac | |
|
|
b9ee133acb | |
|
|
fdac58f4dc | |
|
|
b4e5960462 | |
|
|
e5011512ee | |
|
|
fbafd051a8 | |
|
|
27f33320e6 | |
|
|
aeb019098c | |
|
|
94e2e7cf61 | |
|
|
04fd77c1be | |
|
|
a5dec99e4b | |
|
|
4900c26d51 | |
|
|
2243d00a18 | |
|
|
0af9b52d89 | |
|
|
9bd37dc600 | |
|
|
590d17777d | |
|
|
aae13b1de5 | |
|
|
10115646e9 | |
|
|
95e90279ee | |
|
|
50923319fb | |
|
|
73008adc66 | |
|
|
0c26eda95c | |
|
|
27f9a5f3f3 | |
|
|
4b5a889efc | |
|
|
99f8c96590 | |
|
|
2782a729f0 | |
|
|
9611b90b71 | |
|
|
f2dd59725a | |
|
|
e528941b65 | |
|
|
1408a7f11e | |
|
|
3be4ad6617 | |
|
|
ba9ab39a40 | |
|
|
0bdad0f3da | |
|
|
e57da0ddd5 | |
|
|
d2a88e1cd0 | |
|
|
5a33068e2b | |
|
|
a471b3121b | |
|
|
b886d79879 | |
|
|
ff8880dd2a | |
|
|
b366733a52 | |
|
|
37155b3563 | |
|
|
e271d55fa7 | |
|
|
0e18651ff6 | |
|
|
d25377cdbe | |
|
|
bda0b385ae | |
|
|
c7240f9167 | |
|
|
ee899f9f90 | |
|
|
59c4f9f89e | |
|
|
70817ad3a0 | |
|
|
a27d5890a8 | |
|
|
67d9ce7802 | |
|
|
46b4e1dcd0 | |
|
|
219120fe71 | |
|
|
7bad3c6045 | |
|
|
1b6e16e9fe | |
|
|
e66a2114c5 | |
|
|
b78cf09e23 |
|
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
.git
|
||||
.gitignore
|
||||
|
|
@ -29,6 +29,14 @@
|
|||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"test": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.test.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,20 +21,24 @@
|
|||
"@angular/platform-browser": "~7.2.0",
|
||||
"@angular/platform-browser-dynamic": "~7.2.0",
|
||||
"@angular/router": "~7.2.0",
|
||||
"chart.js": "^2.9.3",
|
||||
"chartjs-plugin-datalabels": "^0.7.0",
|
||||
"core-js": "^2.5.4",
|
||||
"hammerjs": "^2.0.8",
|
||||
"luxon": "^1.22.0",
|
||||
"rxjs": "~6.3.3",
|
||||
"tslib": "^1.9.0",
|
||||
"zone.js": "~0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.12.0",
|
||||
"@angular/cli": "~7.2.2",
|
||||
"@angular/cli": "^7.3.8",
|
||||
"@angular/compiler-cli": "~7.2.0",
|
||||
"@angular/language-service": "~7.2.0",
|
||||
"@types/node": "~8.9.4",
|
||||
"@types/jasmine": "~2.8.8",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "~8.9.4",
|
||||
"@types/chart.js": "^2.9.7",
|
||||
"codelyzer": "~4.5.0",
|
||||
"jasmine-core": "~2.99.1",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,15 @@ 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';
|
||||
import { ContributorYearlyReportComponent } from './components/contributor-yearly-report/contributor-yearly-report.component';
|
||||
import { ContributorAllReportsComponent } from './components/contributor-all-reports/contributor-all-reports.component';
|
||||
import { LiveStreamComponent } from './components/live-stream/live-stream.component';
|
||||
import { VideoServicesComponent } from './components/video-services/video-services.component';
|
||||
import { ImageComponent } from './components/image/image.component';
|
||||
import { VideoComponent } from './components/video/video.component';
|
||||
import { FCCPermitPageComponent } from './components/fcc-permit-page/fcc-permit-page.component';
|
||||
import { BalloonComponent } from './components/balloon/balloon.component';
|
||||
|
||||
const routes =
|
||||
[
|
||||
|
|
@ -36,10 +45,18 @@ const routes =
|
|||
path: 'contact',
|
||||
component: ContactPageComponent
|
||||
},
|
||||
{
|
||||
path: 'missionary',
|
||||
component: MissionaryFormPageComponent
|
||||
},
|
||||
{
|
||||
path: 'sermons',
|
||||
component: SermonsComponent
|
||||
},
|
||||
{
|
||||
path: 'video',
|
||||
component: VideoComponent
|
||||
},
|
||||
{
|
||||
path: 'sermons/:id',
|
||||
component: SermonsComponent
|
||||
|
|
@ -64,13 +81,45 @@ const routes =
|
|||
path: 'user',
|
||||
component: MembersPageComponent
|
||||
},
|
||||
{
|
||||
path: 'covid',
|
||||
component: ImageComponent,
|
||||
data: {
|
||||
imageUrl: 'assets/images/tiny/covid_tract.jpg',
|
||||
shareName: 'covid'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'covid2',
|
||||
component: ImageComponent,
|
||||
data: {
|
||||
imageUrl: 'assets/images/tiny/covid_tract_2.jpg',
|
||||
shareName: 'covid2'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'camp',
|
||||
component: CampPageComponent
|
||||
},
|
||||
{
|
||||
path: 'live',
|
||||
component: LiveStreamComponent
|
||||
},
|
||||
{
|
||||
path: 'transactions/add',
|
||||
component: AddTransactionPageComponent
|
||||
},
|
||||
{
|
||||
path: 'contributor/report',
|
||||
component: ContributorAllReportsComponent
|
||||
},
|
||||
{
|
||||
path: 'fmpermit',
|
||||
component: FCCPermitPageComponent
|
||||
},
|
||||
{
|
||||
path: 'balloon',
|
||||
component: BalloonComponent
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { GoogleAnalyticsService } from './services/google-analytics.service';
|
|||
import { WindowRefService } from './services/window-ref.service';
|
||||
import { EmailService } from './services/email.service';
|
||||
import { SermonService } from './services/sermon.service';
|
||||
import { PrintService } from './services/print-service';
|
||||
import { LoginService } from './services/login.service';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
|
@ -15,7 +16,9 @@ import { MatButtonModule,
|
|||
MatDialogModule,
|
||||
MatSelectModule,
|
||||
MatOptionModule,
|
||||
MatAutocompleteModule} from '@angular/material';
|
||||
MatRadioModule,
|
||||
MatAutocompleteModule,
|
||||
MatCheckboxModule} from '@angular/material';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import 'hammerjs';
|
||||
|
||||
|
|
@ -50,6 +53,8 @@ import { EventLargeComponent } from './components/event-large/event-large.compon
|
|||
import { SalvationPageComponent } from './components/salvation-page/salvation-page.component';
|
||||
import { MediaPageComponent } from './components/media-page/media-page.component';
|
||||
import { VideoPopupComponent } from './components/popups/video-popup/video-popup.component';
|
||||
import { FCCPermitPageComponent } from './components/fcc-permit-page/fcc-permit-page.component';
|
||||
import { BalloonComponent } from './components/balloon/balloon.component';
|
||||
|
||||
//Directives
|
||||
import { FadeInOnScrollDirective } from './directives/fade-in-on-scroll.directive';
|
||||
|
|
@ -68,6 +73,20 @@ import { AddUserPopupComponent } from './components/popups/add-user-popup/add-us
|
|||
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';
|
||||
import { ContributorYearlyReportComponent } from './components/contributor-yearly-report/contributor-yearly-report.component';
|
||||
import { ContributorAllReportsComponent } from './components/contributor-all-reports/contributor-all-reports.component';
|
||||
import { LiveStreamComponent } from './components/live-stream/live-stream.component';
|
||||
import { VideoServicesComponent } from './components/video-services/video-services.component';
|
||||
import { ImageComponent } from './components/image/image.component';
|
||||
import { YoutubeListComponent } from './components/youtube-list/youtube-list.component';
|
||||
import { VideoComponent } from './components/video/video.component';
|
||||
import { YoutubeListService } from './components/youtube-list/youtube-list-service';
|
||||
import { VideoItemComponent } from './components/video-item/video-item.component';
|
||||
import { YoutubePopupComponent } from './components/popups/youtube-popup/youtube-popup.component';
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -92,6 +111,7 @@ import { AddTransactionPageComponent } from './components/add-transaction-page/a
|
|||
DurationPipe,
|
||||
LocationComponent,
|
||||
SermonLargeComponent,
|
||||
VideoServicesComponent,
|
||||
AddSermonPopupComponent,
|
||||
LoginPopupComponent,
|
||||
OkPopupComponent,
|
||||
|
|
@ -110,8 +130,20 @@ import { AddTransactionPageComponent } from './components/add-transaction-page/a
|
|||
VideoPopupComponent,
|
||||
CampPageComponent,
|
||||
MembersPageComponent,
|
||||
FCCPermitPageComponent,
|
||||
BalloonComponent,
|
||||
AddUserPopupComponent,
|
||||
AddTransactionPageComponent
|
||||
AddTransactionPageComponent,
|
||||
AddTransactionPopupComponent,
|
||||
MissionaryFormPageComponent,
|
||||
ContributorYearlyReportComponent,
|
||||
ContributorAllReportsComponent,
|
||||
LiveStreamComponent,
|
||||
ImageComponent,
|
||||
YoutubeListComponent,
|
||||
VideoComponent,
|
||||
VideoItemComponent,
|
||||
YoutubePopupComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
|
@ -128,9 +160,11 @@ import { AddTransactionPageComponent } from './components/add-transaction-page/a
|
|||
MatSliderModule,
|
||||
MatSnackBarModule,
|
||||
MatDialogModule,
|
||||
MatAutocompleteModule
|
||||
MatAutocompleteModule,
|
||||
MatRadioModule,
|
||||
MatCheckboxModule
|
||||
],
|
||||
providers: [LoginService,UserService,GoogleAnalyticsService,SermonService,TransactionService,EventService,EmailService,WindowRefService],
|
||||
providers: [LoginService,PrintService,UserService,GoogleAnalyticsService,SermonService,TransactionService,EventService,EmailService,MissionarySupportService,YoutubeListService,WindowRefService],
|
||||
entryComponents: [AddSermonPopupComponent,
|
||||
LoginPopupComponent,
|
||||
OkPopupComponent,
|
||||
|
|
@ -140,7 +174,9 @@ import { AddTransactionPageComponent } from './components/add-transaction-page/a
|
|||
SharePopupComponent,
|
||||
AddEventPopupComponent,
|
||||
AddUserPopupComponent,
|
||||
VideoPopupComponent],
|
||||
VideoPopupComponent,
|
||||
AddTransactionPopupComponent,
|
||||
YoutubePopupComponent],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
|
|
|||
|
|
@ -1,72 +1,73 @@
|
|||
.d-inline-block {
|
||||
display: inline-block;
|
||||
.b-0 {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.fw-b {
|
||||
.fab-buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fw-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.w-5 {
|
||||
width: 5%;
|
||||
.fs-1-2-5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.w-15 {
|
||||
width: 15%;
|
||||
.highlight {
|
||||
background-color: #F3FAFF;
|
||||
}
|
||||
|
||||
.w-20 {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.w-30 {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.w-75 {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.w-80 {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.m-1 {
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.mt-1 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 2rem;
|
||||
.highlight-yellow {
|
||||
background-color: lightyellow;
|
||||
}
|
||||
|
||||
.ml-1 {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.ml-2 {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
.mr-1 {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.pt-1 {
|
||||
padding-top: 1rem;
|
||||
.p-0 {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bb-1 {
|
||||
border-bottom: 1px solid #ff4081;
|
||||
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
td, th {
|
||||
padding: 5px;
|
||||
border: 1px solid orange;
|
||||
border: 1px solid lightslategray;
|
||||
}
|
||||
|
||||
.remove-top-border {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.remove-border {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.side-bar > button {
|
||||
margin: 20px;
|
||||
width: calc(100% - 40px);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#audio-player-filler{
|
||||
height: 60px;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
@media(max-width:800px){
|
||||
.fab-buttons{
|
||||
display: inline-block;
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,116 +3,87 @@
|
|||
|
||||
<secondary-page-component [fixedSideBar]="true" >
|
||||
<div mainContent>
|
||||
<form [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||
<div formArrayName="contributions" *ngFor="let item of form.get('contributions').controls; let i = index;">
|
||||
<div class="m-1 mt-2 bb-1" [formGroupName]="i">
|
||||
<button class="w-5" type="button" mat-icon-button (click)="deleteContributor(i)">
|
||||
<i ofbicon>delete_forever</i>
|
||||
</button>
|
||||
<mat-form-field class="w-20">
|
||||
<input matInput placeholder="Date" type="date" formControlName="date" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-75">
|
||||
<input type="text" placeholder="Contributor" aria-label="Contributor" matInput formControlName="contributorId" (ngModelChange)="onContributorChange($event)" [matAutocomplete]="auto">
|
||||
<mat-autocomplete #auto="matAutocomplete" [displayWith]="contirbutorDisplayFn">
|
||||
<mat-option *ngFor="let option of filteredContributors" [value]="option">
|
||||
{{option.display}}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
<div formArrayName="transactions" *ngFor="let trans of item.get('transactions').controls; let a = index;">
|
||||
<div [formGroupName]="a">
|
||||
<button class="w-5" type="button" mat-icon-button (click)="deleteTransaction(i,a)">
|
||||
<i ofbicon>delete_forever</i>
|
||||
</button>
|
||||
<mat-form-field class="w-15">
|
||||
<mat-select formControlName="typeId">
|
||||
<mat-option *ngFor="let type of types" [value]="type.value" >
|
||||
{{type.display}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-20">
|
||||
<input matInput placeholder="Check Number" type="text" formControlName="checkNumber" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-20">
|
||||
<mat-select formControlName="fundId">
|
||||
<mat-option *ngFor="let fund of funds" [value]="fund.value">
|
||||
{{fund.display}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-20">
|
||||
<input matInput placeholder="Amount" type="number" formControlName="amount" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-20">
|
||||
<input matInput placeholder="Description" type="text" formControlName="description" >
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<button class="w-15" mat-stroked-button type="button" (click)="addTransaction(i)">Add Transaction</button>
|
||||
<div class="ml-1 w-20 d-inline-block">
|
||||
{{contributorName(i)}}
|
||||
</div>
|
||||
<div class="ml-1 w-20 d-inline-block">
|
||||
General: {{contributorTotal(i, 1)}}
|
||||
</div>
|
||||
<div class="w-15 d-inline-block">
|
||||
Missions: {{contributorTotal(i, 2)}}
|
||||
</div>
|
||||
<div class="w-15 d-inline-block">
|
||||
Total: {{contributorTotal(i, 0)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button mat-stroked-button class="m-1 w-15" type="button" (click)="addContributor()">Add Contributor</button>
|
||||
<div class="ml-1 w-20 d-inline-block">
|
||||
Combined
|
||||
</div>
|
||||
<div class="ml-1 w-20 d-inline-block">
|
||||
General: {{combinedTotal(1)}}
|
||||
</div>
|
||||
<div class="w-15 d-inline-block">
|
||||
Missions: {{combinedTotal(2)}}
|
||||
</div>
|
||||
<div class="w-15 d-inline-block">
|
||||
Total: {{combinedTotal(0)}}
|
||||
</div>
|
||||
<button mat-raised-button type="submit" [disabled]="!form.valid || submitButtonDisabled">{{ submitButtonText }}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>General</th>
|
||||
<th>Missions</th>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<ng-container *ngFor="let c of form.get('contributions').value; let i = index">
|
||||
<tr>
|
||||
<td colspan="3" class="pt-1">{{contributorName(i)}}</td>
|
||||
<ng-container *ngFor="let c of contributions; let ci = index">
|
||||
<tr [class.bg-red]="!contributorDatesMatch(c.contributorId)">
|
||||
<td colspan="2" class="fw-bold fs-1-2-5">{{c.date}}</td>
|
||||
<td colspan="4" class="fw-bold fs-1-2-5">{{contributorName(c.contributorId)}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{contributorTotal(i, 1) | currency}}</td>
|
||||
<td>{{contributorTotal(i, 2) | currency}}</td>
|
||||
<td>{{contributorTotal(i, 0) | currency}}</td>
|
||||
<td></td>
|
||||
<td class="fw-bold">Date</td>
|
||||
<td class="fw-bold">Type</td>
|
||||
<td class="fw-bold">Check</td>
|
||||
<td class="fw-bold">Fund</td>
|
||||
<td class="fw-bold">Amount</td>
|
||||
</tr>
|
||||
<ng-container *ngFor="let t of c.transactions; let ti = index">
|
||||
<tr [class.highlight]="ti % 2">
|
||||
<td rowspan="2" style="width: 30px;">
|
||||
<button mat-icon-button (click)="deleteTransaction(t.contributorId, ti)"><i ofbicon>delete_forever</i></button>
|
||||
</td>
|
||||
<td colspan="5" *ngIf="t.description && t.description.length > 0">{{t.description}}</td>
|
||||
<td colspan="5" *ngIf="!t.description || t.description.length === 0" class="b-0 p-0"></td>
|
||||
</tr>
|
||||
<tr [class.highlight]="ti % 2">
|
||||
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{t.date}}</td>
|
||||
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{transactionType[t.typeId]}}</td>
|
||||
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{t.checkNumber}}</td>
|
||||
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{fund[t.fundId]}}</td>
|
||||
<td [class.remove-top-border]="!t.description || t.description.length === 0">{{t.amount | currency}}</td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<tr>
|
||||
<td colspan="3" class="pt-1">
|
||||
Total
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="fw-bold">General</td>
|
||||
<td class="fw-bold">Missions</td>
|
||||
<td class="fw-bold">Total</td>
|
||||
</tr>
|
||||
<tr class="highlight-yellow">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>{{contributorTotal(c.contributorId, 1) | currency}}</td>
|
||||
<td>{{contributorTotal(c.contributorId, 2) | currency}}</td>
|
||||
<td>{{contributorTotal(c.contributorId, 0) | currency}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<button mat-raised-button (click)="addTransaction(c.contributorId)" >Add Transaction to {{contributorName(c.contributorId)}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<tr>
|
||||
<td colspan="6" class="fw-bold fs-1-2-5">Grand Totals</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="fw-bold">General</td>
|
||||
<td class="fw-bold">Missions</td>
|
||||
<td class="fw-bold">Total</td>
|
||||
</tr>
|
||||
<tr class="highlight-yellow">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>{{combinedTotal(1) | currency}}</td>
|
||||
<td>{{combinedTotal(2) | currency}}</td>
|
||||
<td>{{combinedTotal(0) | currency}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="fab-buttons" >
|
||||
<button mat-fab (click)="addTransaction(-1)"><i ofbicon>add</i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
<button mat-raised-button (click)="addTransaction(-1)" >Add Transaction</button>
|
||||
<button mat-raised-button (click)="submit()" [disabled]="contributions.length === 0 || submitButtonDisabled" >{{submitButtonText}}</button>
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Transaction } from './transaction';
|
||||
import { UserService } from 'src/app/services/user.service';
|
||||
import { UserService } from '../../services/user.service';
|
||||
import { Contribution } from './contribution';
|
||||
import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms';
|
||||
import { checkNumberValidator } from './check-number-validator';
|
||||
import { contributorValidator } from './contributor-validator';
|
||||
import { TransactionService } from 'src/app/services/transaction.service';
|
||||
import { TransactionService } from '../../services/transaction.service';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { AddTransactionPopupComponent, ValDisplay } from './add-transaction-popup/add-transaction-popup.component';
|
||||
import { TransactionType } from './transaction-type';
|
||||
import { Fund } from './fund';
|
||||
import { OkPopupComponent } from '../popups/ok-popup/ok-popup.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-add-transaction-page',
|
||||
|
|
@ -16,114 +18,115 @@ export class AddTransactionPageComponent implements OnInit {
|
|||
|
||||
errorMessages = [];
|
||||
|
||||
form: FormGroup;
|
||||
contributions: Contribution[] = [];
|
||||
|
||||
submitButtonDisabled: boolean = false;
|
||||
submitButtonText: string = "Submit";
|
||||
types: {value:number,display:string}[] = [];
|
||||
funds: {value:number,display:string}[] = [];
|
||||
submitButtonText: string = "Submit Transactions";
|
||||
transactionType = TransactionType;
|
||||
fund = Fund;
|
||||
transactionTypes: ValDisplay[] = [];
|
||||
funds: ValDisplay[] = [];
|
||||
contributors: {value:number,display:string}[] = [];
|
||||
filteredContributors: {value:number,display:string}[]
|
||||
|
||||
|
||||
|
||||
constructor(private userService: UserService, private formBuilder: FormBuilder, private transactionService: TransactionService) {
|
||||
this.form = this.formBuilder.group({
|
||||
contributions: this.formBuilder.array([this.getContribution()])
|
||||
});
|
||||
constructor(private dialogService: MatDialog, private userService: UserService, private transactionService: TransactionService) {
|
||||
for(let m in TransactionType) {
|
||||
if (typeof TransactionType[m] === 'number') {
|
||||
this.transactionTypes.push({value:<any>TransactionType[m], display: m});
|
||||
}
|
||||
}
|
||||
for(let m in Fund) {
|
||||
if (typeof Fund[m] === 'number') {
|
||||
this.funds.push({value:<any>Fund[m], display: m});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.types = [{value:1, display: 'Cash'},{value:2, display: 'Check'}];
|
||||
this.funds = [{value:1, display: 'General'},{value:2, display: 'Missions'}];
|
||||
this.userService.getAll().subscribe(res => this.contributors = (<any>res).users);
|
||||
}
|
||||
|
||||
getContribution(): FormGroup {
|
||||
const date = new Date();
|
||||
const dte = date.getFullYear() + "-" + (date.getMonth()<10?'0':'') + (date.getMonth() + 1) + "-" + (date.getDate()<10?'0':'') + date.getDate();
|
||||
|
||||
return this.formBuilder.group({
|
||||
date: [dte, Validators.required],
|
||||
contributorId: [0, [Validators.required, contributorValidator(this)]],
|
||||
transactions: this.formBuilder.array([this.getTransaction()])
|
||||
|
||||
|
||||
addTransaction(contributorId: number) {
|
||||
const contrib = this.contributors.find(c => c.value === contributorId);
|
||||
const contributor = this.contributions.find(c => c.contributorId === contributorId);
|
||||
const lastTransaction = contributor && contributor.transactions.length > 0 ? contributor.transactions[contributor.transactions.length-1] : null;
|
||||
|
||||
const ref = this.dialogService.open(AddTransactionPopupComponent, {
|
||||
data: {
|
||||
contributors: this.contributors,
|
||||
funds: this.funds,
|
||||
types: this.transactionTypes,
|
||||
contributor: contrib ? contrib : undefined,
|
||||
typeId: lastTransaction ? lastTransaction.typeId : TransactionType.Cash,
|
||||
fundId: lastTransaction ? (lastTransaction.fundId === Fund.General ? Fund.Missions : Fund.General) : Fund.General,
|
||||
checkNumber: lastTransaction ? lastTransaction.checkNumber : '',
|
||||
goodsOrServices: false
|
||||
}
|
||||
});
|
||||
|
||||
ref.afterClosed().subscribe((res: {transaction:Transaction,saveAndAdd:boolean}) => {
|
||||
if (res) {
|
||||
let contrib = this.contributions.find(c => c.contributorId === res.transaction.contributorId);
|
||||
if (!contrib) {
|
||||
contrib = new Contribution();
|
||||
contrib.contributorId = res.transaction.contributorId;
|
||||
contrib.date = res.transaction.date;
|
||||
contrib.transactions = [];
|
||||
this.contributions.push(contrib);
|
||||
}
|
||||
res.transaction.taxYear = +res.transaction.date.split('-')[0];
|
||||
contrib.transactions.push(res.transaction);
|
||||
if (res.saveAndAdd === true) {
|
||||
this.addTransaction(contrib.contributorId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
getTransaction(): FormGroup {
|
||||
return this.formBuilder.group({
|
||||
amount: [null, Validators.required],
|
||||
checkNumber: [''],
|
||||
description: [''],
|
||||
fundId: [1, [Validators.required, Validators.min(1), Validators.max(2)]],
|
||||
taxYear: [(new Date()).getFullYear(), Validators.required],
|
||||
typeId: [1, [Validators.required, Validators.min(1), Validators.max(2)]],
|
||||
}, { validators: checkNumberValidator });
|
||||
}
|
||||
|
||||
onContributorChange(event) {
|
||||
if (event && event.value) {
|
||||
if (event.value === -1) {
|
||||
// Open new user dialog
|
||||
}
|
||||
event = event.display;
|
||||
}
|
||||
const filterValue = event.toLowerCase();
|
||||
this.filteredContributors = this.contributors.filter(option => option.display.toLowerCase().indexOf(filterValue) >= 0);
|
||||
if (this.filteredContributors.length === 0) {
|
||||
this.filteredContributors.push({value:-1, display:'Add New Contributor'});
|
||||
deleteContributor(contributorId: number) {
|
||||
const contrib = this.contributions.findIndex(c => c.contributorId === contributorId);
|
||||
if (contrib >= 0) {
|
||||
this.contributions.splice(contrib, 1);
|
||||
}
|
||||
}
|
||||
|
||||
contirbutorDisplayFn(contributor?: {value:number,display:string}): string | undefined {
|
||||
deleteTransaction(contributorId: number, transactionIndex: number) {
|
||||
const contrib = this.contributions.find(c => c.contributorId === contributorId);
|
||||
if (contrib) {
|
||||
contrib.transactions.splice(transactionIndex, 1);
|
||||
}
|
||||
if (contrib.transactions.length === 0) {
|
||||
this.deleteContributor(contributorId);
|
||||
}
|
||||
}
|
||||
|
||||
contributorName(id: number) {
|
||||
const contributor = this.contributors.find(c => c.value === id);
|
||||
return contributor ? contributor.display : undefined;
|
||||
}
|
||||
|
||||
addTransaction(contributorPosition: number) {
|
||||
const contributors = this.form.get('contributions') as FormArray;
|
||||
const transactions = contributors.controls[contributorPosition].get('transactions') as FormArray;
|
||||
const lastTransaction = transactions.value.length > 0 ? transactions.value[transactions.value.length-1] : undefined;
|
||||
console.log(lastTransaction);
|
||||
const newTransaction = this.getTransaction();
|
||||
if (lastTransaction) {
|
||||
newTransaction.patchValue({
|
||||
"typeId": lastTransaction.typeId,
|
||||
"checkNumber": lastTransaction.checkNumber,
|
||||
"fundId": lastTransaction.fundId === 1 ? 2 : 1
|
||||
contributorDatesMatch(contributorId: number) {
|
||||
const contributor = this.contributions.find(c => c.contributorId === contributorId);
|
||||
if (!contributor) return true;
|
||||
let match = true;
|
||||
contributor.transactions.forEach(t => {
|
||||
if (t.date != contributor.date) {
|
||||
match = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
transactions.push(newTransaction);
|
||||
return match;
|
||||
}
|
||||
|
||||
addContributor() {
|
||||
const contributors = this.form.get('contributions') as FormArray;
|
||||
contributors.push(this.getContribution());
|
||||
}
|
||||
contributorTotal(contributorId: number, fundId: number) {
|
||||
const contrib = this.contributions.find(c => c.contributorId === contributorId);
|
||||
if (!contrib) return 0;
|
||||
|
||||
deleteContributor(index: number) {
|
||||
const contributors = this.form.get('contributions') as FormArray;
|
||||
contributors.removeAt(index);
|
||||
}
|
||||
|
||||
deleteTransaction(contributorIndex: number, transactionIndex: number) {
|
||||
const contributors = this.form.get('contributions') as FormArray;
|
||||
const transactions = contributors.controls[contributorIndex].get('transactions') as FormArray;
|
||||
transactions.removeAt(transactionIndex);
|
||||
}
|
||||
|
||||
contributorName(index: number) {
|
||||
const contributors = this.form.get('contributions') as FormArray;
|
||||
const contributor = contributors.controls[index].get('contributorId');
|
||||
if (contributor && contributor.value.display) {
|
||||
return contributor.value.display;
|
||||
}
|
||||
}
|
||||
|
||||
contributorTotal(index: number, fundId: number) {
|
||||
const contributors = this.form.get('contributions') as FormArray;
|
||||
const transactions = contributors.controls[index].get('transactions').value;
|
||||
var sum = 0;
|
||||
transactions.forEach(e => {
|
||||
contrib.transactions.forEach(e => {
|
||||
if (e.fundId === fundId || fundId === 0) {
|
||||
sum += e.amount;
|
||||
}
|
||||
|
|
@ -132,9 +135,8 @@ export class AddTransactionPageComponent implements OnInit {
|
|||
}
|
||||
|
||||
combinedTotal(fundId: number) {
|
||||
const contributors = this.form.get('contributions').value;
|
||||
var sum = 0;
|
||||
contributors.forEach(c => {
|
||||
this.contributions.forEach(c => {
|
||||
c.transactions.forEach(t => {
|
||||
if (t.fundId === fundId || fundId === 0) {
|
||||
sum += +t.amount;
|
||||
|
|
@ -144,25 +146,29 @@ export class AddTransactionPageComponent implements OnInit {
|
|||
return sum;
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
submit() {
|
||||
this.submitButtonText = 'Submitting...';
|
||||
this.submitButtonDisabled = true;
|
||||
var data = this.form.value;
|
||||
|
||||
const transactions: Transaction[] = [];
|
||||
for(let c = 0; c < data.contributions.length; c++) {
|
||||
const contribution = data.contributions[c] as Contribution;
|
||||
for(let t = 0; t < contribution.transactions.length; t++) {
|
||||
const transaction = contribution.transactions[t] as Transaction;
|
||||
transaction.contributorId = (<any>contribution.contributorId).value;
|
||||
transaction.date = contribution.date;
|
||||
transactions.push(transaction);
|
||||
for(let c = 0; c < this.contributions.length; c++) {
|
||||
for(let t = 0; t < this.contributions[c].transactions.length; t++) {
|
||||
transactions.push(this.contributions[c].transactions[t]);
|
||||
}
|
||||
}
|
||||
console.log(transactions);
|
||||
|
||||
this.transactionService.createFromArray(transactions).subscribe(x =>{
|
||||
this.submitButtonText = 'Submit';
|
||||
this.submitButtonText = 'Submit Transactions';
|
||||
this.submitButtonDisabled = false;
|
||||
}, e => console.log(e));
|
||||
this.contributions = [];
|
||||
}, e => {
|
||||
this.dialogService.open(OkPopupComponent,{
|
||||
data: {
|
||||
title: 'Error Saving Transactions',
|
||||
message: e.toString()
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.w-50 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.m-5 {
|
||||
margin: 5px;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<div md-dialog-title>
|
||||
<p>Add Transaction</p>
|
||||
</div>
|
||||
<div md-dialog-content>
|
||||
<form [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Date" type="date" formControlName="date" >
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" placeholder="Contributor" aria-label="Contributor" matInput formControlName="contributor" (ngModelChange)="onContributorChange($event)" [matAutocomplete]="auto">
|
||||
<mat-autocomplete #auto="matAutocomplete" [displayWith]="contributorDisplayFn">
|
||||
<mat-option *ngFor="let option of filteredContributors" [value]="option">
|
||||
{{option.display}}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
<button mat-button class="m-5" type="button" (click)="addUser()">Add</button>
|
||||
<br>
|
||||
<mat-form-field class="w-50">
|
||||
<mat-select formControlName="typeId">
|
||||
<mat-option *ngFor="let type of types" [value]="type.value" >
|
||||
{{type.display}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-50">
|
||||
<input matInput placeholder="Check Number" type="text" formControlName="checkNumber" >
|
||||
</mat-form-field>
|
||||
<div></div>
|
||||
<mat-form-field class="w-50">
|
||||
<mat-select formControlName="fundId">
|
||||
<mat-option *ngFor="let fund of funds" [value]="fund.value">
|
||||
{{fund.display}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-50">
|
||||
<input matInput placeholder="Amount" type="number" formControlName="amount" >
|
||||
</mat-form-field>
|
||||
<br>
|
||||
<mat-form-field class="w-100">
|
||||
<input matInput placeholder="Description" type="text" formControlName="description" >
|
||||
</mat-form-field>
|
||||
<br>
|
||||
<mat-checkbox formControlName="goodsOrServices">Goods Or Services Received?</mat-checkbox>
|
||||
<br>
|
||||
<br>
|
||||
<button mat-raised-button class="m-5" type="button" (click)="cancel()" >Cancel</button>
|
||||
<button mat-raised-button class="m-5" type="submit" [disabled]="!form.valid || saveBtnDisabled">{{ saveBtnTxt }}</button>
|
||||
<button mat-raised-button class="m-5" type="button" (click)="onSubmit(true)" [disabled]="!form.valid || saveBtnDisabled">{{ saveAndAddBtnTxt }}</button>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AddTransactionPopupComponent } from './add-transaction-popup.component';
|
||||
|
||||
describe('AddTransactionPopupComponent', () => {
|
||||
let component: AddTransactionPopupComponent;
|
||||
let fixture: ComponentFixture<AddTransactionPopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AddTransactionPopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddTransactionPopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef, MatDialog } from '@angular/material';
|
||||
import { contributorValidator } from '../contributor-validator';
|
||||
import { Transaction } from '../transaction';
|
||||
import { AddUserPopupComponent } from '../../popups/add-user-popup/add-user-popup.component';
|
||||
|
||||
export interface ValDisplay {
|
||||
value: number;
|
||||
display: string;
|
||||
}
|
||||
|
||||
export interface DialogData {
|
||||
contributors: ValDisplay[],
|
||||
funds: ValDisplay[],
|
||||
types: ValDisplay[],
|
||||
contributor: ValDisplay,
|
||||
date: string,
|
||||
typeId: number,
|
||||
fundId: number,
|
||||
checkNumber: string,
|
||||
description: string,
|
||||
taxYear: number,
|
||||
goodsOrServices: boolean
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-add-transaction-popup',
|
||||
templateUrl: './add-transaction-popup.component.html',
|
||||
styleUrls: ['./add-transaction-popup.component.css']
|
||||
})
|
||||
export class AddTransactionPopupComponent implements OnInit {
|
||||
|
||||
form: FormGroup;
|
||||
|
||||
saveBtnDisabled: boolean = false;
|
||||
saveBtnTxt: string = 'Save';
|
||||
saveAndAddBtnTxt: string = 'Save & Add';
|
||||
contributors: ValDisplay[] = [];
|
||||
filteredContributors: ValDisplay[]
|
||||
funds: ValDisplay[];
|
||||
types: ValDisplay[];
|
||||
|
||||
constructor(private dialogService: MatDialog, private formBuilder: FormBuilder, @Inject(MAT_DIALOG_DATA) public data: DialogData, private dialogRef:MatDialogRef<AddTransactionPopupComponent>) {
|
||||
this.contributors = this.data.contributors || [];
|
||||
this.funds = this.data.funds || [];
|
||||
this.types = this.data.types || [];
|
||||
|
||||
const date = new Date();
|
||||
const dte = date.getFullYear() + "-" + (date.getMonth()<10?'0':'') + (date.getMonth() + 1) + "-" + (date.getDate()<10?'0':'') + date.getDate();
|
||||
|
||||
this.form = this.formBuilder.group({
|
||||
date: [this.data.date || dte, [Validators.required]],
|
||||
contributor: [this.data.contributor, [Validators.required, contributorValidator(this.contributors)]],
|
||||
typeId: [this.data.typeId || 1, [Validators.required]],
|
||||
fundId: [this.data.fundId || 1, [Validators.required]],
|
||||
checkNumber: [this.data.checkNumber],
|
||||
description: [this.data.description],
|
||||
amount: ['', [Validators.required]],
|
||||
taxYear: [this.data.taxYear || new Date().getFullYear(), [Validators.required]],
|
||||
goodsOrServices: [this.data.goodsOrServices || false]
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
contributorDisplayFn(contributor?: {value:number,display:string}): string | undefined {
|
||||
return contributor ? contributor.display : undefined;
|
||||
}
|
||||
|
||||
onContributorChange(event) {
|
||||
if (event && event.value) {
|
||||
if (event.value === -1) {
|
||||
// Open new user dialog
|
||||
}
|
||||
event = event.display;
|
||||
}
|
||||
const filterValue = event.toLowerCase();
|
||||
this.filteredContributors = this.contributors.filter(option => option.display.toLowerCase().indexOf(filterValue) >= 0);
|
||||
if (this.filteredContributors.length === 0) {
|
||||
this.filteredContributors.push({value:-1, display:'Add New Contributor'});
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit(saveAndAdd: boolean = false) {
|
||||
const trans = new Transaction();
|
||||
trans.amount = this.form.value.amount;
|
||||
trans.checkNumber = this.form.value.checkNumber;
|
||||
trans.contributorId = this.form.value.contributor.value;
|
||||
trans.date = this.form.value.date;
|
||||
trans.description = this.form.value.description;
|
||||
trans.fundId = this.form.value.fundId;
|
||||
trans.taxYear = this.form.value.taxYear;
|
||||
trans.typeId = this.form.value.typeId;
|
||||
trans.goodsOrServices = this.form.value.goodsOrServices;
|
||||
this.dialogRef.close({transaction:trans,saveAndAdd:saveAndAdd});
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
addUser() {
|
||||
const ref = this.dialogService.open(AddUserPopupComponent);
|
||||
|
||||
ref.afterClosed().subscribe((res: any) => {
|
||||
if (res && res.id > 0) {
|
||||
|
||||
this.contributors.push({ value: res.id, display: res.lastName + ' ' + res.firstName });
|
||||
|
||||
let contrib = this.contributors.find(c => c.value === res.id);
|
||||
|
||||
this.form.get("contributor").setValue(contrib);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
import { ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms';
|
||||
import { AddTransactionPageComponent } from './add-transaction-page.component';
|
||||
|
||||
export function contributorValidator(comp: AddTransactionPageComponent): ValidatorFn {
|
||||
export function contributorValidator(contributors: {value:number,display:string}[]): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
const val = control.value;
|
||||
const error = {'invalidName':{value: val}};
|
||||
if (!val || !val.value) {
|
||||
return error;
|
||||
}
|
||||
const contributor = comp.contributors.findIndex(c => c.value === val.value);
|
||||
const contributor = contributors.findIndex(c => c.value === val.value);
|
||||
if (contributor >= 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
export enum Fund {
|
||||
General = 1,
|
||||
Missions = 2
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export enum TransactionType {
|
||||
Cash = 1,
|
||||
Check = 2
|
||||
}
|
||||
|
|
@ -7,4 +7,5 @@ export class Transaction {
|
|||
fundId: number;
|
||||
taxYear: number;
|
||||
typeId: number;
|
||||
goodsOrServices: boolean;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
header{
|
||||
div.header{
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
|
|
@ -51,7 +51,7 @@ header{
|
|||
padding-bottom: 140px;
|
||||
}
|
||||
|
||||
footer{
|
||||
div.footer{
|
||||
background-color: rgb(50,50,50);
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
|
|
@ -81,7 +81,7 @@ footer{
|
|||
}
|
||||
|
||||
@media(max-width: 800px){
|
||||
footer{
|
||||
div.footer{
|
||||
height: 380px;
|
||||
}
|
||||
.footer-panel{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
<header>
|
||||
<div class="header" [class.print-hide]="printService.isPrinting">
|
||||
<div id="header-background" [ngStyle]="{'opacity':headerOpacity}"></div>
|
||||
<button mat-button class="header-button-home" routerLink="/home"><img id="logo" src="assets/images/tiny/logo.png" height="30" alt="logo"> Old Fashion Baptist</button>
|
||||
<span class="hideOnMobile"></span>
|
||||
|
|
@ -12,13 +12,13 @@
|
|||
(click)="mainMenuClick()">
|
||||
<i ofbicon class="example-icon" style="line-height:20px;">menu</i>
|
||||
</button>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="content" [class.print-hide-children]="printService.isPrinting">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div class="footer" [class.print-hide]="printService.isPrinting">
|
||||
<div id="footer-content">
|
||||
<div id="footer-contact-content" class="footer-panel">
|
||||
<a target="_blank" href="https://www.google.com/maps/place/Old+Fashion+Baptist+Church/@45.9814004,-112.5320574,11.87z/data=!4m12!1m6!3m5!1s0x535b078c3c74ea33:0xac299097142c5894!2sOld+Fashion+Baptist+Church!8m2!3d45.951287!4d-112.511978!3m4!1s0x535b078c3c74ea33:0xac299097142c5894!8m2!3d45.951287!4d-112.511978">
|
||||
|
|
@ -27,8 +27,9 @@
|
|||
</a>
|
||||
<p><a href="tel:+1-406-494-5028" class="phone">(406) 494 - 5028</a></p>
|
||||
<p>Pastor Derek Loewen</p>
|
||||
<p>Pastor Emeritus Ron Derksen</p>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div id="footer-services-content" class="footer-panel">
|
||||
<p>Sunday School: 10AM</p>
|
||||
<p>Sunday Worship: 11AM</p>
|
||||
|
|
@ -40,14 +41,14 @@
|
|||
<p><i ofbicon class="copyright">copyright</i> Copyright {{copyrightYear}}</p>
|
||||
<p>Old Fashion Baptist</p>
|
||||
<p><a routerLink="/home">ofbbutte.com</a></p>
|
||||
<p>Powered by God</p>
|
||||
<p><a href="https://publicfiles.fcc.gov/fm-profile/KFGL" target="_blank">KFGL Public Information File</a></p>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
<div class="audio-player-filler" [hidden]="!showAudioPlayer" ></div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<div class="audio-player" [class.audio-player-slide-up]="showAudioPlayer">
|
||||
<div class="audio-player" [class.audio-player-slide-up]="showAudioPlayer" [class.print-hide]="printService.isPrinting">
|
||||
<audio-player-component (closed)="audioPlayerClosed()" (started)="audioPlayerStarted()"></audio-player-component>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { Router, NavigationEnd, Event } from '@angular/router';
|
|||
import { EventService } from '../../services/event.service';
|
||||
import { AudioPlayerService } from '../../services/audio-player.service';
|
||||
import { BibleVerseService } from '../../services/bible-verse.service';
|
||||
import { PrintService } from '../../services/print-service';
|
||||
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -26,7 +27,8 @@ export class AppComponent {
|
|||
|
||||
constructor(private router: Router,
|
||||
private audioPlayerService: AudioPlayerService,
|
||||
private googleAnalyticsService: GoogleAnalyticsService){
|
||||
private googleAnalyticsService: GoogleAnalyticsService,
|
||||
public printService: PrintService){
|
||||
this.router.events.subscribe((event:Event) => {
|
||||
if(event instanceof NavigationEnd) {
|
||||
this.lastRoute = this.currRoute;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
.full-width{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hide{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.margin-top-space {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.errorMessages{
|
||||
color: white;
|
||||
background-color: rgb(255,90,90);
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<br>
|
||||
<p class="bold">
|
||||
We are so glad you found one of our balloons. We would love to hear from you
|
||||
and where you found it!
|
||||
</p>
|
||||
<p class="margin-top-space">
|
||||
Click <a routerLink="/whoweare">here</a> to learn more about us.
|
||||
</p>
|
||||
<p class="margin-top-space">
|
||||
Click <a routerLink="/salvation">here</a> to learn more about <span class="bold">Jesus</span>.
|
||||
</p>
|
||||
<br>
|
||||
<div *ngIf="!formSubmitted">
|
||||
<form class="form" #contactForm="ngForm" (ngSubmit)="onSubmit()">
|
||||
<mat-form-field class="full-width">
|
||||
<input matInput type="text" placeholder="Name" required value="" [(ngModel)]="name" name="name" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="full-width">
|
||||
<input matInput type="text" placeholder="City, State" required value="" [(ngModel)]="location" name="location" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="full-width">
|
||||
<input matInput type="email" placeholder="Email" value="" [(ngModel)]="email" name="email" pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="full-width">
|
||||
<input matInput type="tel" placeholder="Phone" value="" [(ngModel)]="phone" name="phone">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="full-width">
|
||||
<textarea matInput type="text" placeholder="Other Information or Questions" value="" [(ngModel)]="body" name="body" rows="5" ></textarea>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="hide">
|
||||
<input matInput type="text" placeholder="hp" required value="" [(ngModel)]="hp" name="subject">
|
||||
</mat-form-field>
|
||||
<div class="errorMessages" *ngIf="errorMessages.length > 0">
|
||||
<p *ngFor="let error of errorMessages">{{error}}</p>
|
||||
</div>
|
||||
<button mat-raised-button type="submit" [disabled]="!contactForm.form.valid || submitButtonDisabled">{{submitButtonText}}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div *ngIf="formSubmitted">
|
||||
<p><b>Thank You!</b></p>
|
||||
<p>Your message has been sent.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar ofbFadeInOnScroll>
|
||||
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BalloonComponent } from './balloon.component';
|
||||
|
||||
describe('BalloonComponent', () => {
|
||||
let component: BalloonComponent;
|
||||
let fixture: ComponentFixture<BalloonComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ BalloonComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BalloonComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
import { Router } from '@angular/router';
|
||||
import { MatDialogConfig } from '@angular/material';
|
||||
import { OkPopupComponent } from '../popups/ok-popup/ok-popup.component';
|
||||
import { EmailService } from '../../services/email.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-contact-page',
|
||||
templateUrl: './balloon.component.html',
|
||||
styleUrls: ['./balloon.component.css']
|
||||
})
|
||||
export class BalloonComponent implements OnInit {
|
||||
public submitButtonText: string = "Submit";
|
||||
public submitButtonDisabled: boolean = false;
|
||||
public formSubmitted: boolean = false;
|
||||
|
||||
public name: string;
|
||||
public email: string;
|
||||
public location: string;
|
||||
public phone: string;
|
||||
public body: string;
|
||||
public hp: string = ".";
|
||||
|
||||
public errorMessages: string[] = [];
|
||||
|
||||
|
||||
constructor(private emailService: EmailService,
|
||||
private MatDialog: MatDialog,
|
||||
private router: Router) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
onSubmit(){
|
||||
this.errorMessages = [];
|
||||
if (this.name == null || this.name == ""){
|
||||
this.errorMessages.push("Please enter a name");
|
||||
}
|
||||
if (this.location == null || this.location == ""){
|
||||
this.errorMessages.push("Please enter a city and state");
|
||||
}
|
||||
if (this.errorMessages.length > 0){ return; }
|
||||
|
||||
const body = `Location of balloon: ${this.location}<br>${this.body || ''}`;
|
||||
let email = this.email;
|
||||
if (!email || email.length === 0) {
|
||||
email = 'N/A';
|
||||
}
|
||||
|
||||
this.submitButtonText = "Please Wait...";
|
||||
this.submitButtonDisabled = true;
|
||||
this.emailService.sendEmail(this.name,
|
||||
email,
|
||||
this.phone || '',
|
||||
body,
|
||||
this.hp)
|
||||
.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.formSubmitted = true;
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<br>
|
||||
<p>
|
||||
For general questions please complete the form below. If you are a missionary requesting
|
||||
support please complete the <a routerLink="/missionary">Missionary Questionnaire form by clicking here.</a>
|
||||
</p>
|
||||
<br>
|
||||
<div *ngIf="!formSubmitted">
|
||||
<form class="form" #contactForm="ngForm" (ngSubmit)="onSubmit()">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
@media print {
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
<app-contributor-yearly-report *ngFor="let c of contributors; let i = index" [index]="i" [contributorTransactions]="c">
|
||||
</app-contributor-yearly-report>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ContributorAllReportsComponent } from './contributor-all-reports.component';
|
||||
|
||||
describe('ContributorAllReportsComponent', () => {
|
||||
let component: ContributorAllReportsComponent;
|
||||
let fixture: ComponentFixture<ContributorAllReportsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ContributorAllReportsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ContributorAllReportsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { PrintService } from 'src/app/services/print-service';
|
||||
import { UserService } from 'src/app/services/user.service';
|
||||
import { TransactionService } from 'src/app/services/transaction.service';
|
||||
import { forkJoin } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-contributor-all-reports',
|
||||
templateUrl: './contributor-all-reports.component.html',
|
||||
styleUrls: ['./contributor-all-reports.component.css']
|
||||
})
|
||||
export class ContributorAllReportsComponent implements OnInit {
|
||||
|
||||
public contributors: {contributor:{}, transactions:[]}[] = [];
|
||||
|
||||
constructor(private printService: PrintService, private userService: UserService, private transactionService: TransactionService) { }
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
const taxYear = 2024;
|
||||
|
||||
const query = forkJoin([this.userService.getAll(), this.transactionService.getByYear(taxYear), this.transactionService.getByYear(taxYear - 1)]);
|
||||
|
||||
|
||||
query.subscribe(res => this.setup(res[0], res[1], res[2]));
|
||||
|
||||
this.printService.setPrinting(true);
|
||||
}
|
||||
|
||||
private setup(contributorResult, transactionResult, priorYearTransactionResult) {
|
||||
const contributors = contributorResult.users;
|
||||
const transactions = transactionResult.transactions;
|
||||
const priorYearTransactions = priorYearTransactionResult.transactions;
|
||||
const contrib = {};
|
||||
transactions.forEach(t => {
|
||||
if (contrib.hasOwnProperty(t.contributorId)) {
|
||||
contrib[t.contributorId].transactions.push(t);
|
||||
} else {
|
||||
const con = contributors.find(c => c.id === t.contributorId);
|
||||
if (con) {
|
||||
contrib[con.id] = {contributor: con, transactions: [t]};
|
||||
contrib[con.id].priorYearTransactions = priorYearTransactions.filter(t => t.contributorId === con.id);
|
||||
this.contributors.push(contrib[con.id]);
|
||||
} else {
|
||||
console.error('coould not find contributor for', t);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
@media screen {
|
||||
:host {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
:host {
|
||||
display: block;
|
||||
margin-top: -50px;
|
||||
-webkit-print-color-adjust: exact;
|
||||
color-adjust: exact;
|
||||
}
|
||||
tr.page-break-after:after { content:""; display: block; page-break-before: always; }
|
||||
}
|
||||
|
||||
.h-100 {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.d-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-grow-1 {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.flex-direction-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-align-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-justify-space-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex-align-space-between {
|
||||
align-content: space-between;
|
||||
}
|
||||
|
||||
.flex-align-top {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.flex-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.flex-justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-justify-space-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top: 1px solid green;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.mt-5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mt-20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.mb-20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.mr-40 {
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
.flex-direction-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-break-before {
|
||||
page-break-before: always;
|
||||
}
|
||||
|
||||
.fw-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hilight-yellow {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
table.borders {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.borders th, table.borders tr.row td {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
table.cell-padding-5 td, table.cell-padding-5 th {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
table.highlight-even tr.row:nth-child(even) {
|
||||
background-color: #e6ffe6;
|
||||
}
|
||||
|
||||
table tbody tr.footer td {
|
||||
font-size: small;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.text-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
|
||||
<div *ngIf="index > 0" class="page-break-before"></div>
|
||||
<div class="h-100 flex flex-align-center flex-justify-center flex-direction-column">
|
||||
<img src="../../../assets/images/original/logo_dark.png">
|
||||
<p class="mt-5">
|
||||
Old Fashion Baptist Church Giving Statement {{taxYear}}
|
||||
</p>
|
||||
<p class="mt-5">
|
||||
{{contributorName}}
|
||||
</p>
|
||||
<p *ngIf="contributorStreet && contributorCity && contributorState && contributorZip">{{contributorStreet}}</p>
|
||||
<p *ngIf="contributorStreet && contributorCity && contributorState && contributorZip">{{contributorCity}} {{contributorState}}, {{contributorZip}}</p>
|
||||
</div>
|
||||
|
||||
<div class="page-break-before">
|
||||
<div class="header flex flex-justify-space-between">
|
||||
<div>
|
||||
<img src="../../../assets/images/original/logo_dark.png">
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p>Old Fashion Baptist Church</p>
|
||||
<p>5003 Wynne Ave</p>
|
||||
<p>Butte, MT 59701</p>
|
||||
<p>(406) 494-5028</p>
|
||||
<p>ofbbutte.com</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="hr mt-20">
|
||||
<h2 class="text-center mt-20">Old Fashion Baptist Church Giving Statement {{taxYear}}</h2>
|
||||
<hr class="mt-20">
|
||||
<div class="flex flex-align-stretch flex-justify-space-between">
|
||||
<div class="mt-20 mb-20 mr-40 flex-grow-1 flex flex-direction-column flex-justify-space-between">
|
||||
<div class="mt-20">
|
||||
<p><b>Name: </b>{{contributorName}}</p>
|
||||
<p><b>Year: </b>{{taxYear}}</p>
|
||||
</div>
|
||||
<table class="cell-padding-5 borders w-100">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">{{taxYear}} Giving Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="cell-padding-5">
|
||||
<tr class="row">
|
||||
<td class="fw-bold">General Fund</td>
|
||||
<td class="text-right">{{totalGeneral() | currency}}</td>
|
||||
</tr>
|
||||
<tr class="row">
|
||||
<td class="fw-bold">Missions Fund</td>
|
||||
<td class="text-right">{{totalMissions() | currency}}</td>
|
||||
</tr>
|
||||
<tr class="row">
|
||||
<td class="fw-bold">Total Giving</td>
|
||||
<td class="text-right hilight-yellow">{{(totalGeneral() + totalMissions()) | currency}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div>
|
||||
Thank you for your support. The information provided in this statement reflects
|
||||
your gifts on record for {{taxYear}}.
|
||||
No goods or services were provided in exchange for your contributions.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-20">
|
||||
<canvas #chart width="400" height="300"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="highlight-even cell-padding-5 w-100 borders mt-20">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-left">Date</th>
|
||||
<th nowrap class="text-left">Payment Type</th>
|
||||
<th nowrap class="text-left">Check Number</th>
|
||||
<th class="text-left">Fund</th>
|
||||
<th class="text-left">Description</th>
|
||||
<th class="text-left">Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<ng-container *ngFor="let t of transactions; let i = index">
|
||||
<tr class="row">
|
||||
<td nowrap>{{t.date | date:'MM-dd-yyyy':'UTC'}}</td>
|
||||
<td nowrap>{{t.typeId === 1 ? 'Cash' : (t.typeId === 2 ? 'Check' : 'NA')}}</td>
|
||||
<td nowrap>{{t.checkNumber}}</td>
|
||||
<td nowrap>{{t.fundId === 1 ? 'General' : (t.fundId === 2 ? 'Missions' : 'NA')}}</td>
|
||||
<td width="99%">{{t.description}}</td>
|
||||
<td nowrap class="text-align-right">{{t.amount | currency}}</td>
|
||||
</tr>
|
||||
<tr *ngIf="isFooter(i+1)" class="footer page-break-after">
|
||||
<td colspan="6">
|
||||
<div class="flex flex-justify-space-between">
|
||||
<p>Old Fashion Baptist Church Giving Statement {{taxYear }}</p>
|
||||
<p>Page {{calcPage(i+1)}} of {{pages}}</p>
|
||||
</div>
|
||||
</td>
|
||||
<div></div><!--DIV IS HERE TO MAKE PAGE BREAKS WORK CORRECTLY-->
|
||||
</tr>
|
||||
</ng-container>
|
||||
<ng-container *ngFor="let r of fillerRows; let i = index">
|
||||
<tr>
|
||||
<td nowrap> </td>
|
||||
<td nowrap></td>
|
||||
<td nowrap></td>
|
||||
<td nowrap></td>
|
||||
<td width="99%"></td>
|
||||
<td nowrap></td>
|
||||
</tr>
|
||||
<tr *ngIf="i === fillerRows.length-1" class="footer">
|
||||
<td colspan="6">
|
||||
<div class="flex flex-justify-space-between">
|
||||
<p>Old Fashion Baptist Church Giving Statement {{taxYear}}</p>
|
||||
<p>Page {{pages}} of {{pages}}</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
</tbody>
|
||||
</table>
|
||||
<div *ngIf="pagesOdd" class="page-break-before"> </div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ContributorYearlyReportComponent } from './contributor-yearly-report.component';
|
||||
|
||||
describe('ContributorYearlyReportComponent', () => {
|
||||
let component: ContributorYearlyReportComponent;
|
||||
let fixture: ComponentFixture<ContributorYearlyReportComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ContributorYearlyReportComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ContributorYearlyReportComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core';
|
||||
import { PrintService } from '../../services/print-service';
|
||||
import { Transaction } from '../add-transaction-page/transaction';
|
||||
import * as Chart from 'chart.js';
|
||||
import ChartDataLabels from 'chartjs-plugin-datalabels';
|
||||
import { CurrencyPipe } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-contributor-yearly-report',
|
||||
templateUrl: './contributor-yearly-report.component.html',
|
||||
styleUrls: ['./contributor-yearly-report.component.css']
|
||||
})
|
||||
export class ContributorYearlyReportComponent implements OnInit {
|
||||
|
||||
@ViewChild('chart') chartElement:ElementRef;
|
||||
@Input() index: number;
|
||||
@Input() contributorTransactions: {contributor: {}, transactions: {}, priorYearTransactions: {}};
|
||||
public transactions: Transaction[] = [];
|
||||
public priorTransactions: Transaction[] = [];
|
||||
public get contributorName(): string {
|
||||
const first = (<any>this.contributorTransactions.contributor).firstName;
|
||||
const last = (<any>this.contributorTransactions.contributor).lastName;
|
||||
if (last && first) {
|
||||
return last + ', ' + first;
|
||||
} else if (last) {
|
||||
return last;
|
||||
} else if (first) {
|
||||
return first;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
public contributorStreet: string = '7878 Washington St';
|
||||
public contributorCity: string = 'Butte';
|
||||
public contributorState: string = 'MT';
|
||||
public contributorZip: string = '59701';
|
||||
public taxYear: number = 2024;
|
||||
|
||||
|
||||
public rowsFirstPage: number = 11;
|
||||
public rowsPerPage: number = 30;
|
||||
public get fillerRows(): number[] {
|
||||
const rowsToFillPage = this.rowsFirstPage + ((this.pages - 2) * this.rowsPerPage);
|
||||
const rowsNeeded = rowsToFillPage - this.transactions.length;
|
||||
return Array(rowsNeeded).fill(1).map((x,i)=>i)
|
||||
}
|
||||
public get pages(): number {
|
||||
return Math.ceil((this.transactions.length - this.rowsFirstPage) / this.rowsPerPage) + 2;
|
||||
}
|
||||
public get pagesOdd(): boolean {
|
||||
return !(this.pages % 2 == 0)
|
||||
}
|
||||
private currencyPipe: CurrencyPipe = new CurrencyPipe('en-US');
|
||||
|
||||
constructor(public printService: PrintService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.contributorCity = (<any>this.contributorTransactions.contributor).city;
|
||||
this.contributorState = (<any>this.contributorTransactions.contributor).state;
|
||||
this.contributorStreet = (<any>this.contributorTransactions.contributor).street;
|
||||
this.contributorZip = (<any>this.contributorTransactions.contributor).zip;
|
||||
this.transactions = <any>this.contributorTransactions.transactions;
|
||||
this.priorTransactions = <any>this.contributorTransactions.priorYearTransactions;
|
||||
this.renderChart();
|
||||
}
|
||||
|
||||
public totalGeneral() {
|
||||
let sum = 0;
|
||||
this.transactions.filter(t => t.fundId === 1).forEach(t => sum += t.amount);
|
||||
return sum;
|
||||
}
|
||||
|
||||
public priorGeneral() {
|
||||
let sum = 0;
|
||||
this.priorTransactions.filter(t => t.fundId === 1).forEach(t => sum += t.amount);
|
||||
return sum;
|
||||
}
|
||||
|
||||
public totalMissions() {
|
||||
let sum = 0;
|
||||
this.transactions.filter(t => t.fundId === 2).forEach(t => sum += t.amount);
|
||||
return sum;
|
||||
}
|
||||
|
||||
public priorMissions() {
|
||||
let sum = 0;
|
||||
this.priorTransactions.filter(t => t.fundId === 2).forEach(t => sum += t.amount);
|
||||
return sum;
|
||||
}
|
||||
|
||||
public calcPage(index: number): number {
|
||||
const val = Math.max(index, this.rowsFirstPage);
|
||||
return Math.ceil((val - this.rowsFirstPage) / this.rowsPerPage) + 2;
|
||||
}
|
||||
|
||||
public isFooter(index: number): boolean {
|
||||
if (index === this.rowsFirstPage) {
|
||||
return true;
|
||||
}
|
||||
if (index === (this.rowsFirstPage + ((this.calcPage(index) - 2) * this.rowsPerPage))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private renderChart() {
|
||||
const me = this;
|
||||
var myChart = new Chart(this.chartElement.nativeElement, {
|
||||
plugins: [ChartDataLabels],
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [(this.taxYear - 1).toString(), this.taxYear.toString()],
|
||||
datasets: [{
|
||||
label: 'General',
|
||||
data: [this.priorGeneral(), this.totalGeneral()],
|
||||
backgroundColor: 'rgba(54, 245, 162, 0.2)',
|
||||
borderColor: 'rgba(54, 245, 162, 1)',
|
||||
borderWidth: 1
|
||||
}, {
|
||||
label: 'Missions',
|
||||
data: [this.priorMissions(), this.totalMissions()],
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options:{
|
||||
scales: {
|
||||
xAxes: [{
|
||||
stacked: true
|
||||
}],
|
||||
yAxes: [{
|
||||
stacked: true,
|
||||
ticks: {
|
||||
callback: function(value, index, values) {
|
||||
return me.currencyPipe.transform(value, 'USD', 'symbol', '1.0-0');
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
plugins:{
|
||||
datalabels:{
|
||||
font:{
|
||||
weight: 'bold'
|
||||
},
|
||||
formatter: function(value, context){
|
||||
if (value === 0) {
|
||||
return '';
|
||||
}
|
||||
return me.currencyPipe.transform(value, 'USD', 'symbol', '1.0-2');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
.section-header{
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid gray;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
a{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
a:visited{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.break-word {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
|
||||
-ms-word-break: break-all;
|
||||
word-break: break-word;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true">
|
||||
<div mainContent>
|
||||
<p ofbFadeInOnScroll class="section-header">FCC Noncommercial FM Radio Station Construction Permit</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
On November 9, 2021, Old Fashion Baptist Church of Butte, applicant for a Noncommercial FM Radio Station on
|
||||
88.1mhz, in Butte, MT, filed an application with the Federal Communications Commission for a new Noncommercial FM
|
||||
Station. Members of the public wishing to view this application or obtain information about how to file comments and
|
||||
petitions on the application can visit <a class="break-word" href="https://enterpriseefiling.fcc.gov/dataentry/views/public/nceDraftCopy?displayType=html&appKey=25076f917cce2f5b0
|
||||
17cd34cdd450dee&id=25076f917cce2f5b017cd34cdd450dee&goBack=N">https://enterpriseefiling.fcc.gov/dataentry/views/public/nceDraftCopy?displayType=html&appKey=25076f917cce2f5b0
|
||||
17cd34cdd450dee&id=25076f917cce2f5b017cd34cdd450dee&goBack=N</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-fcc-permit-page',
|
||||
templateUrl: './fcc-permit-page.component.html',
|
||||
styleUrls: ['./fcc-permit-page.component.css']
|
||||
})
|
||||
export class FCCPermitPageComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
import { DateTime } from "luxon";
|
||||
import { VideoServices, VideoService } from './video-services';
|
||||
|
||||
export class Countdown {
|
||||
public days: number = 0;
|
||||
public hours: number = 0;
|
||||
public minutes: number = 0;
|
||||
public seconds: number = 0;
|
||||
public services: VideoService[] = [];
|
||||
public showButton: boolean;
|
||||
public showCounter: boolean = false;
|
||||
|
||||
public dateDisplay: string;
|
||||
public dateDisplaySmall: string;
|
||||
|
||||
public get daysDisplay(): string {
|
||||
return this.formatDisplay(this.days);
|
||||
}
|
||||
|
||||
public get daysText(): string {
|
||||
return this.days === 1 ? 'day ' : 'days';
|
||||
}
|
||||
|
||||
public get hoursDisplay(): string {
|
||||
return this.formatDisplay(this.hours);
|
||||
}
|
||||
|
||||
public get hoursText(): string {
|
||||
return this.hours === 1 ? 'hr ' : 'hrs';
|
||||
}
|
||||
|
||||
public get minutesDisplay(): string {
|
||||
return this.formatDisplay(this.minutes);
|
||||
}
|
||||
|
||||
public get minutesText(): string {
|
||||
return this.minutes === 1 ? 'min ' : 'mins';
|
||||
}
|
||||
|
||||
public get secondsDisplay(): string {
|
||||
return this.formatDisplay(this.seconds);
|
||||
}
|
||||
|
||||
public get secondsText(): string {
|
||||
return this.seconds === 1 ? 'sec ' : 'secs';
|
||||
}
|
||||
|
||||
private clock;
|
||||
|
||||
constructor(services: VideoService[]) {
|
||||
if (!services || services.length == 0) return;
|
||||
this.services = services;
|
||||
this.services.forEach(v => {
|
||||
v.date = DateTime.fromISO(v.date, {zone: 'America/Denver'})
|
||||
});
|
||||
this.services.sort((a, b) => {
|
||||
if (a.date < b.date) return -1;
|
||||
if (a.date === b.date) return 0;
|
||||
return 1;
|
||||
});
|
||||
this.updateClock();
|
||||
this.startClock();
|
||||
}
|
||||
|
||||
private resetToZero() {
|
||||
this.days = 0;
|
||||
this.hours = 0;
|
||||
this.minutes = 0;
|
||||
this.seconds = 0;
|
||||
}
|
||||
|
||||
private updateClock() {
|
||||
this.showCounter = true;
|
||||
var now = DateTime.local();
|
||||
|
||||
var firstNonArchived = this.getFirstNonArchived(now);
|
||||
if (!firstNonArchived) {
|
||||
this.stopClock();
|
||||
this.resetToZero();
|
||||
this.showCounter = false;
|
||||
this.dateDisplay = '';
|
||||
this.dateDisplaySmall = '';
|
||||
return;
|
||||
}
|
||||
|
||||
var hourDiff = (<DateTime>firstNonArchived.date).diff(now, ['hours']);
|
||||
if (hourDiff.hours >= 48) {
|
||||
this.showCounter = false;
|
||||
this.dateDisplay = '';
|
||||
this.dateDisplaySmall = '';
|
||||
return;
|
||||
}
|
||||
|
||||
var secDiff = (<DateTime>firstNonArchived.date).diff(now, ['seconds']);
|
||||
if (secDiff.seconds <= 0) {
|
||||
this.showButton = true;
|
||||
}
|
||||
|
||||
var diff = (<DateTime>firstNonArchived.date).diff(now, ['days', 'hours', 'minutes', 'seconds']);
|
||||
this.days = diff.days;
|
||||
this.hours = diff.hours;
|
||||
this.minutes = diff.minutes;
|
||||
this.seconds = Math.floor(diff.seconds);
|
||||
this.dateDisplay = firstNonArchived.date.toLocaleString(DateTime.DATETIME_HUGE);
|
||||
this.dateDisplaySmall = firstNonArchived.date.toLocaleString(DateTime.DATETIME_MED)
|
||||
}
|
||||
|
||||
private startClock() {
|
||||
this.clock = setInterval(this.updateClock.bind(this), 1000);
|
||||
}
|
||||
|
||||
private stopClock() {
|
||||
clearInterval(this.clock);
|
||||
}
|
||||
|
||||
private getFirstNonArchived(now: DateTime): VideoService {
|
||||
if (this.services.length === 0) return null;
|
||||
const nonArchived = this.services.filter(s => s.archived === false);
|
||||
if (!nonArchived || nonArchived.length === 0) return null;
|
||||
return nonArchived[0];
|
||||
}
|
||||
|
||||
private getNearestPastDate(now: DateTime): VideoService {
|
||||
if (this.services.length === 0) return null;
|
||||
const archived = this.services.filter(s => s.archived === false);
|
||||
if (!archived || archived.length === 0) return null;
|
||||
|
||||
var now = now || DateTime.local();
|
||||
var nearestIndex = archived.findIndex(s => s.date > now);
|
||||
if (nearestIndex === 0) return null;
|
||||
if (nearestIndex === -1) return archived[archived.length - 1];
|
||||
return archived[nearestIndex - 1];
|
||||
}
|
||||
|
||||
private getNearestFutureDate(now: DateTime): VideoService {
|
||||
if (this.services.length === 0) return null;
|
||||
var now = now || DateTime.local();
|
||||
var nearest = this.services.find(s => s.date > now);
|
||||
return nearest;
|
||||
}
|
||||
|
||||
private formatDisplay(val: number): string {
|
||||
if (val <= 0) {
|
||||
return '00';
|
||||
}
|
||||
if (val < 10) {
|
||||
return '0' + val.toString();
|
||||
}
|
||||
return val.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -7,21 +7,42 @@ a{
|
|||
color: inherit;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a:visited{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
img{
|
||||
width: 70%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
img.w-100pct {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
img.full {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.color-white {
|
||||
color: white;
|
||||
}
|
||||
|
||||
#call-to-action-container {
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
|
|
@ -30,6 +51,128 @@ img.full {
|
|||
bottom: 10%;
|
||||
}
|
||||
|
||||
#live-stream-container {
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
left: 10%;
|
||||
right: 0;
|
||||
bottom: 20%;
|
||||
}
|
||||
|
||||
#title > .live {
|
||||
display: inline-block;
|
||||
background-color: red;
|
||||
color: white;
|
||||
padding: 0px 7px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#live-date {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#live-stream-container > #title {
|
||||
font-size: 25pt;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
font-family: Franklin Gothic Medium,Franklin Gothic,ITC Franklin Gothic,Arial,sans-serif;
|
||||
}
|
||||
|
||||
#countdown-container {
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
margin-top: 7px;
|
||||
display: inline-block;
|
||||
font-size: 30pt;
|
||||
font-weight: bold;
|
||||
border-radius: 10px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
padding: 15px 20px;
|
||||
-webkit-box-shadow: inset 0px 0px 20px -15px rgba(0,0,0,1);
|
||||
-moz-box-shadow: inset 0px 0px 20px -15px rgba(0,0,0,1);
|
||||
box-shadow: inset 0px 0px 20px -15px rgba(0,0,0,1);
|
||||
border: 1px solid green;
|
||||
font-family: Consolas,monaco,monospace;
|
||||
}
|
||||
|
||||
/*Button*/
|
||||
#countdown-container.show-button {
|
||||
background-color:#2dabf9;
|
||||
color:#ffffff;
|
||||
text-shadow:0px 1px 0px #263666;
|
||||
}
|
||||
#countdown-container.show-button:hover {
|
||||
background-color:#0688fa;
|
||||
}
|
||||
#countdown-container.show-button:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
|
||||
/*End Button*/
|
||||
|
||||
#countdown-container .text {
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.opacity-zero {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#live-button {
|
||||
position: absolute;
|
||||
font-size: 25pt;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media(max-width:900px){
|
||||
#live-stream-container > #title {
|
||||
font-size: 18pt;
|
||||
}
|
||||
#countdown-container {
|
||||
font-size: 20pt;
|
||||
}
|
||||
#live-button {
|
||||
font-size: 20pt;
|
||||
}
|
||||
}
|
||||
|
||||
.display-sm {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media(max-width:600px){
|
||||
#live-stream-container {
|
||||
left: 5%;
|
||||
right: 5%;
|
||||
bottom: 5%
|
||||
}
|
||||
#live-stream-container > #title {
|
||||
font-size: 13pt;
|
||||
}
|
||||
#countdown-container {
|
||||
font-size: 13pt;
|
||||
margin-top: 3px;
|
||||
}
|
||||
.display-none-sm {
|
||||
display: none;
|
||||
}
|
||||
.display-sm {
|
||||
display: block;
|
||||
}
|
||||
#live-date {
|
||||
margin-top: 2px;
|
||||
}
|
||||
#live-button {
|
||||
font-size: 18pt;
|
||||
margin-top: -5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#action-button {
|
||||
font-size: 16pt;
|
||||
max-width: 100%;
|
||||
|
|
@ -39,6 +182,18 @@ img.full {
|
|||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.w-200 {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.h-200 {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.action{
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
|
|
@ -175,7 +330,9 @@ img.full {
|
|||
margin: 10px;
|
||||
}
|
||||
|
||||
|
||||
img.m-100-lg {
|
||||
margin-left: 100px;
|
||||
}
|
||||
|
||||
@media(max-width: 850px){
|
||||
.row-content-col-left, .row-content-col-right{
|
||||
|
|
@ -187,5 +344,16 @@ img.full {
|
|||
img.full {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
img.m-100-lg {
|
||||
margin-left: 0;
|
||||
}
|
||||
img.w-100pct {
|
||||
width: 65%;
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width: 600px) {
|
||||
img.w-100pct {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,38 +2,112 @@
|
|||
<img id="background-image" src="assets/images/home-images/tiny/sunset_b.jpg" alt="background image" width="100%">
|
||||
|
||||
<div id="filler">
|
||||
<div id="live-stream-container" *ngIf="showCountdown && countdown && countdown.showCounter">
|
||||
<div id="title">
|
||||
<span class="live">VIDEO</span>
|
||||
<span *ngIf="!countdown.showButton"> SERVICE STARTS IN</span>
|
||||
<span *ngIf="countdown.showButton"> SERVICE AVAILABLE NOW</span>
|
||||
</div>
|
||||
<a id="countdown-container" routerLink="/live" [class.show-button]="countdown.showButton" >
|
||||
<div id="live-button" [class.opacity-zero]="!countdown.showButton">
|
||||
<i ofbicon class="mr-10" >live_tv</i>
|
||||
Click to Watch
|
||||
</div>
|
||||
<div [class.opacity-zero]="countdown.showButton">
|
||||
<span class="number">{{countdown.daysDisplay}}</span>
|
||||
<span class="text"> {{countdown.daysText}}</span>
|
||||
<span class="number"> {{countdown.hoursDisplay}}</span>
|
||||
<span class="text"> {{countdown.hoursText}}</span>
|
||||
<span class="number"> {{countdown.minutesDisplay}}</span>
|
||||
<span class="text"> {{countdown.minutesText}}</span>
|
||||
<span class="number"> {{countdown.secondsDisplay}}</span>
|
||||
<span class="text"> {{countdown.secondsText}}</span>
|
||||
</div>
|
||||
</a>
|
||||
<div id="live-date" class="display-none-sm">
|
||||
{{countdown.dateDisplay}}
|
||||
</div>
|
||||
<div id="live-date" class="display-sm">
|
||||
{{countdown.dateDisplaySmall}}
|
||||
</div>
|
||||
</div>
|
||||
<div id="call-to-action-container" *ngIf="showCallToAction">
|
||||
<button id="action-button" routerLink="/camp" mat-raised-button color="accent"><i ofbicon class="mr-10">info_outline</i>2019 Youth Camp</button>
|
||||
<a id="action-button" href="/assets/Reopening Church Guidelines.pdf" target="_blank" mat-raised-button color="accent"><i ofbicon class="mr-10 color-white">info_outline</i><span class="color-white">Reopening Guidelines</span></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div id="content-wrapper">
|
||||
|
||||
<div class="row tint" *ngIf="showSpecial" >
|
||||
<div style="text-align: center; position: relative; margin-bottom: 15px;" *ngIf="showVBS">
|
||||
<div style="position: absolute; width: 100%; height: calc(65% + 15px); top: 35%; background-color: white;"></div>
|
||||
<img src="assets/images/home-images/tiny/VBS_small.jpg" style="width:75%; max-width: 350px; position: relative; z-index: 1; box-shadow: 0 0 20px pink;" >
|
||||
</div>
|
||||
|
||||
<div class="row tint" *ngIf="showVGC" >
|
||||
<div class="row-content">
|
||||
<div class="row-content-col-left">
|
||||
<a href="assets/images/champ_flyer.jpg" download="champ_flyer.jpg"><img class="full" ofbFadeInOnScroll src="assets/images/home-images/tiny/champ.jpg" height="300"></a>
|
||||
<div class="row-content-col-left center">
|
||||
<img style="max-height:500px" ofbFadeInOnScroll src="assets/images/original/VictoryGospelCrusade.png" height="500">
|
||||
</div>
|
||||
<div class="row-content-col-right align-top">
|
||||
<p ofbFadeInOnScroll class="row-content-header">Victory Gospel Crusade</p>
|
||||
<br />
|
||||
<p ofbFadeInOnScroll class="bold">
|
||||
When
|
||||
</p>
|
||||
<p ofbFadeInOnScroll>
|
||||
August 4 - 9 @ 7PM
|
||||
<br />
|
||||
August 11 - 15 @ 7 PM
|
||||
</p>
|
||||
<br>
|
||||
<p ofbFadeInOnScroll class="bold">
|
||||
Where
|
||||
</p>
|
||||
<p ofbFadeInOnScroll>
|
||||
Behind Pizza Ranch
|
||||
<br />
|
||||
1839 Longfellow St, Butte, Mt
|
||||
<br /><br />
|
||||
<i ofbicon>directions</i> <a target="_blank" class="align-top" href="https://www.google.com/maps/place/1839+Longfellow+St,+Butte,+MT+59701/@45.9732501,-112.513401,17z/data=!3m1!4b1!4m6!3m5!1s0x535b07e062beaaf7:0x827616c9ef692eed!8m2!3d45.9732464!4d-112.5108261!16s%2Fg%2F11v03h9chf?entry=ttu">View Map</a>
|
||||
</p>
|
||||
<p ofbFadeInOnScroll class="action">
|
||||
<i ofbicon>play_arrow</i> <a (click)="playVictoryGospelCrusade()" class="align-top">Click Here To Watch The Trailer</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" *ngIf="showSpecial" >
|
||||
<div class="row-content">
|
||||
<div class="row-content-col-left center">
|
||||
<img style="max-height:500px" ofbFadeInOnScroll src="assets/images/home-images/tiny/Cowboy Carnival.jpg" height="500">
|
||||
</div>
|
||||
<div class="row-content-col-right align-top center">
|
||||
<p ofbFadeInOnScroll class="row-content-header">Champ the Smiling Trick Horse</p>
|
||||
<p ofbFadeInOnScroll class="row-content-header">Cowboy Carnival</p>
|
||||
<p ofbFadeInOnScroll>
|
||||
Come join us for this special event happening September 5th and 6th at Old Fashion Baptist!
|
||||
Come join us for Ranger Walkers Wild West Cowboy Carnival!
|
||||
</p>
|
||||
<br>
|
||||
<p ofbFadeInOnScroll>
|
||||
<b>Wednesday, September 5 @ 7 PM</b>
|
||||
<br>
|
||||
Bible Preaching & Bluegrass Gospel Music
|
||||
<p ofbFadeInOnScroll class="bold">
|
||||
Family Fun
|
||||
</p>
|
||||
<br>
|
||||
<p ofbFadeInOnScroll>
|
||||
<b>Thursday, September 6 @ 5:30 PM</b>
|
||||
<br>
|
||||
Food, Games, Music & Preaching
|
||||
<p ofbFadeInOnScroll class="bold">
|
||||
Games
|
||||
</p>
|
||||
<br>
|
||||
<p ofbFadeInOnScroll>
|
||||
<a href="assets/images/champ_flyer.jpg" download="champ_flyer.jpg"><b>Click here to download the flyer</b></a>
|
||||
<p ofbFadeInOnScroll class="bold">
|
||||
Rides
|
||||
</p>
|
||||
<br>
|
||||
<p ofbFadeInOnScroll class="bold">
|
||||
Inflatables
|
||||
</p>
|
||||
<br>
|
||||
<p ofbFadeInOnScroll style="font-size:1.25em;">
|
||||
<b>Sunday, September 18 @ 11:00 AM</b>
|
||||
</p>
|
||||
<br>
|
||||
<p ofbFadeInOnScroll class="action">
|
||||
|
|
@ -45,7 +119,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="row-content">
|
||||
<div class="row-content-col-left align-top">
|
||||
<div class="row-content-col-right align-top">
|
||||
<p ofbFadeInOnScroll class="row-content-header">...that ye also may have fellowship with us...</p>
|
||||
<p ofbFadeInOnScroll>It is exciting to gather together in the name of the Lord and
|
||||
we sincerily hope that YOU will join us. Guests are always welcome at Old Fashion
|
||||
|
|
@ -53,7 +127,7 @@
|
|||
<p class="verse" ofbFadeInOnScroll>For where two or three are gathered together in my name, there am I in the midst of them. - Matthew 18:20</p>
|
||||
<p ofbFadeInOnScroll class="action"><i ofbicon>info_outline</i> <a href="#" routerLink="/whoweare" class="align-top">Learn more about us</a></p>
|
||||
</div>
|
||||
<div class="row-content-col-right">
|
||||
<div class="row-content-col-left">
|
||||
<!-- <img ofbFadeInOnScroll src="assets/images/home-images/2-church-color.png"> -->
|
||||
<a routerLink="/whoweare"><img ofbFadeInOnScroll src="assets/images/home-images/tiny/family.jpg"></a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ import { Component, HostListener } from '@angular/core';
|
|||
import { MatDialog, MatDialogConfig } from '@angular/material';
|
||||
import { VideoPopupComponent } from '../popups/video-popup/video-popup.component';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { Countdown } from './countdown';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { VideoServices } from './video-services';
|
||||
import { YoutubePopupComponent } from '../popups/youtube-popup/youtube-popup.component';
|
||||
|
||||
@Component({
|
||||
selector: 'home-component',
|
||||
|
|
@ -10,20 +14,55 @@ import { environment } from '../../../environments/environment';
|
|||
})
|
||||
export class HomeComponent {
|
||||
backgroundTop: string = "0px";
|
||||
|
||||
public get showVGC() : boolean {
|
||||
|
||||
let maxDate = new Date(2024,7,15,11); // August 15th 2018 -- Set the month one month behind since JavaScript dates are 0 based
|
||||
let now = new Date();
|
||||
if (now.getFullYear() > maxDate.getFullYear()) return false;
|
||||
if (now.getFullYear() == maxDate.getFullYear()) {
|
||||
if (now.getMonth() > maxDate.getMonth()) return false;
|
||||
if (now.getMonth() == maxDate.getMonth()) {
|
||||
if (now.getDate() > maxDate.getDate()) return false;
|
||||
if (now.getDate() == maxDate.getDate()) {
|
||||
if (now.getHours() > maxDate.getHours()) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public get showSpecial() : boolean {
|
||||
let maxDate = new Date(2018,8,6); // September 6th 2018 -- Set the month one month behind since JavaScript dates are 0 based
|
||||
|
||||
let maxDate = new Date(2022,8,18,11); // September 18th 2018 -- Set the month one month behind since JavaScript dates are 0 based
|
||||
let now = new Date();
|
||||
if (now.getFullYear() > maxDate.getFullYear()) return false;
|
||||
if (now.getFullYear() == maxDate.getFullYear()) {
|
||||
if (now.getMonth() > maxDate.getMonth()) return false;
|
||||
if (now.getMonth() == maxDate.getMonth()) {
|
||||
if (now.getDate() > maxDate.getDate()) return false;
|
||||
if (now.getDate() == maxDate.getDate()) {
|
||||
if (now.getHours() > maxDate.getHours()) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public get showCallToAction(): boolean {
|
||||
let maxDate = new Date(2019,6,8); // September 6th 2018 -- Set the month one month behind since JavaScript dates are 0 based
|
||||
let maxDate = new Date(2020,4,10); // July 8th 2018 -- Set the month one month behind since JavaScript dates are 0 based
|
||||
let now = new Date();
|
||||
if (now.getFullYear() > maxDate.getFullYear()) return false;
|
||||
if (now.getFullYear() == maxDate.getFullYear()) {
|
||||
if (now.getMonth() > maxDate.getMonth()) return false;
|
||||
if (now.getMonth() == maxDate.getMonth()) {
|
||||
if (now.getDate() > maxDate.getDate()) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public get showVBS(): boolean {
|
||||
let maxDate = new Date(2019,7,22); // August 22nd 2018 -- Set the month one month behind since JavaScript dates are 0 based
|
||||
let now = new Date();
|
||||
if (now.getFullYear() > maxDate.getFullYear()) return false;
|
||||
if (now.getFullYear() == maxDate.getFullYear()) {
|
||||
|
|
@ -35,11 +74,26 @@ export class HomeComponent {
|
|||
return true;
|
||||
}
|
||||
|
||||
constructor(private dialog: MatDialog)
|
||||
{
|
||||
public countdown: Countdown;
|
||||
public showCountdown: boolean = false;
|
||||
|
||||
constructor(private dialog: MatDialog, private http: HttpClient)
|
||||
{
|
||||
this.http.get<VideoServices>('assets/json/videoServices.json').subscribe(res => {
|
||||
this.countdown = new Countdown(res.videos);
|
||||
});
|
||||
}
|
||||
|
||||
playVictoryGospelCrusade() {
|
||||
const url = 'https://drive.google.com/file/d/1gPdCTLkJEtNWEyn_y8FQ78PaDi40MU7N/preview'
|
||||
|
||||
let opts = new MatDialogConfig;
|
||||
opts.data = { title: 'Victory Gospel Crusade', embedUrl: url };
|
||||
let dialog = this.dialog.open(YoutubePopupComponent, opts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@HostListener('window:scroll', ['$event'])
|
||||
onScroll(event){
|
||||
let scrollTop = event.target.documentElement.scrollTop || event.target.body.scrollTop || window.pageYOffset;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
export class VideoServices {
|
||||
videos: VideoService[];
|
||||
}
|
||||
|
||||
export class VideoService {
|
||||
isReady: boolean;
|
||||
title: string;
|
||||
src: string;
|
||||
date: Date;
|
||||
archived: boolean;
|
||||
yt: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
.fab-buttons{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.side-bar{
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
@media(max-width:800px){
|
||||
.fab-buttons{
|
||||
display: inline-block;
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent class="mapWrapper">
|
||||
<img style="width: 100%" src="{{imageUrl}}">
|
||||
<div class="fab-buttons" >
|
||||
<button mat-fab (click)="share()"><i ofbicon>share</i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar ofbFadeInOnScroll>
|
||||
<div class="side-bar">
|
||||
<button style="width: 100%;" mat-stroked-button (click)="share()"><i ofbicon>share</i> Share</button>
|
||||
</div>
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import { BibleVerseService } from './../../services/bible-verse.service';
|
||||
import { Component, OnInit, Inject, Input } from '@angular/core';
|
||||
import { MatDialogConfig, MatDialog } from '@angular/material';
|
||||
import { SharePopupComponent } from '../popups/share-popup/share-popup.component';
|
||||
import { DOCUMENT } from '@angular/platform-browser';
|
||||
import { Router, ActivatedRouteSnapshot, ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'image-component',
|
||||
templateUrl: './image.component.html',
|
||||
styleUrls: ['./image.component.css']
|
||||
})
|
||||
export class ImageComponent implements OnInit {
|
||||
|
||||
public imageUrl: string;
|
||||
public shareName: string
|
||||
|
||||
constructor(private dialog: MatDialog, @Inject(DOCUMENT) private document, private route: ActivatedRoute) {
|
||||
this.imageUrl = this.route.snapshot.data.imageUrl;
|
||||
this.shareName = this.route.snapshot.data.shareName;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
// this.bibleVerseService.randomVerse().subscribe(
|
||||
// verse => {
|
||||
|
||||
// },
|
||||
// error => console.log(error) );
|
||||
}
|
||||
|
||||
public share() {
|
||||
let opts = new MatDialogConfig;
|
||||
opts.data = {
|
||||
prefix: 'o',
|
||||
otherName: this.shareName
|
||||
};
|
||||
let dialog = this.dialog.open(SharePopupComponent, opts);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
.video-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 56.25%;
|
||||
}
|
||||
.video-container iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.opacity-zero {
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent class="mapWrapper">
|
||||
<h2 *ngIf="!showVideo">{{message}}</h2>
|
||||
<div class="video-container" *ngIf="showVideo && !yt">
|
||||
<video [class.opacity-zero]="!showVideo" *ngIf="!error" style="width:100%" [src]="videoSrc" controls [poster]="poster" (error)="vidError()"></video>
|
||||
</div>
|
||||
<div *ngIf="showVideo && yt" class="video-container">
|
||||
<iframe [src]="yt | safeUrl" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
<div style="margin-top: 10px">
|
||||
<button routerLink="/video" style="margin-top:5px; width:100%;" mat-stroked-button>
|
||||
<b><i ofbicon style="margin-top:-4px; vertical-align: middle;">play_arrow</i> Click here for previous video services</b>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar ofbFadeInOnScroll>
|
||||
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LiveStreamComponent } from './live-stream.component';
|
||||
|
||||
describe('LiveStreamComponent', () => {
|
||||
let component: LiveStreamComponent;
|
||||
let fixture: ComponentFixture<LiveStreamComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ LiveStreamComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LiveStreamComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import { BibleVerseService } from './../../services/bible-verse.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { VideoServices } from '../home/video-services';
|
||||
import { DateTime } from "luxon";
|
||||
|
||||
@Component({
|
||||
selector: 'live-stream-component',
|
||||
templateUrl: './live-stream.component.html',
|
||||
styleUrls: ['./live-stream.component.css']
|
||||
})
|
||||
export class LiveStreamComponent implements OnInit {
|
||||
|
||||
|
||||
public sermonVideo: string = 'https://ofbbutte.com/static/media/video/sermon.mp4';
|
||||
public pleaseWait: string = 'https://ofbbutte.com/static/media/video/PleaseWait.jpg';
|
||||
public clickToPlay: string = 'https://ofbbutte.com/static/media/video/ClickToPlay.jpg';
|
||||
public message: string = "Please Wait...";
|
||||
public isReady: boolean = false;
|
||||
|
||||
|
||||
public videoSrc: string = this.sermonVideo;
|
||||
public yt: string;
|
||||
public poster: string = this.clickToPlay;
|
||||
public error: boolean = false;
|
||||
public showVideo: boolean = false;
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
private interval;
|
||||
ngOnInit() {
|
||||
this.update();
|
||||
this.interval = setInterval(() => {
|
||||
this.update();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
update() {
|
||||
this.http.get<VideoServices>('assets/json/videoServices.json').subscribe(res => {
|
||||
res.videos = res.videos.filter(v => v.archived === false);
|
||||
res.videos.forEach(v => v.date = DateTime.fromISO(v.date, {zone: 'America/Denver'}));
|
||||
res.videos.sort((a, b) => {
|
||||
if (a.date < b.date) return -1;
|
||||
if (a.date === b.date) return 0;
|
||||
return 1;
|
||||
});
|
||||
var service = res.videos[0];
|
||||
|
||||
if (service) {
|
||||
this.message = (<any>service).message;
|
||||
if (service.isReady === true) {
|
||||
this.showVideo = true;
|
||||
this.videoSrc = '';
|
||||
this.videoSrc = service.src;
|
||||
this.yt = service.yt;
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
} else {
|
||||
this.message = 'No Live Services';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
|
||||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<p class="section-header">
|
||||
Old Fashion Baptist Church Missionary Questionnaire
|
||||
</p>
|
||||
<p>
|
||||
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!
|
||||
<br><br>
|
||||
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.
|
||||
<br><br>
|
||||
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.
|
||||
<br><br>
|
||||
Thank you for your time and understanding. The questions are not meant in any way to be “trick” questions.
|
||||
<br><br>
|
||||
God bless you!
|
||||
<br><br>
|
||||
Pastor Derek Loewen
|
||||
</p>
|
||||
<br><br>
|
||||
<form [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||
<mat-form-field class="w-50" [class.background-error]="hasErrors('name')">
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput type="text" formControlName="name" required>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-50">
|
||||
<mat-label>Wifes Name</mat-label>
|
||||
<input matInput type="text" formControlName="wifesName" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Home Phone</mat-label>
|
||||
<input matInput type="tel" formControlName="homePhone" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Cell Phone</mat-label>
|
||||
<input matInput type="tel" formControlName="cellPhone" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Field Phone</mat-label>
|
||||
<input matInput type="tel" formControlName="fieldPhone" >
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Number of Children</mat-label>
|
||||
<input matInput type="number" formControlName="numberOfChildren" (keyup)="numberOfChildrenChange($event.target.value)" required >
|
||||
</mat-form-field>
|
||||
<div *ngIf="form.get('numberOfChildren').value > 0">
|
||||
<label id="childrenNamesLabel" >Names of Children</label>
|
||||
<ol>
|
||||
<li formArrayName="children" *ngFor="let child of form.get('children').controls; let i = index;">
|
||||
<div [formGroupName]="i">
|
||||
<mat-form-field floatLabel="never" class="w-100">
|
||||
<mat-label>Childs Name</mat-label>
|
||||
<input matInput type="text" formControlName="name" >
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<label id="testimonyLabel">Please give your testimony</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="testimony" aria-labelledby="testimonyLabel" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="callToFieldLabel">Please explain specifically your call to the field.</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="callToField" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="sendingChurchLabel">Sending Church or Missions Board:</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<input matInput type="text" placeholder="Your Answer" formControlName="sendingChurch" required>
|
||||
</mat-form-field>
|
||||
<label id="fieldOfServiceLabel">What is your planned field of Service?</label>
|
||||
<label class="sub">Country and City</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<input matInput type="text" placeholder="Your Answer" formControlName="fieldOfService" required>
|
||||
</mat-form-field>
|
||||
<label id="plansLabel">What do your plans include?</label>
|
||||
<label class="sub">(Starting a church, continuing a church, starting a school, evangelizing the area...)</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="plans" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="evaluationOfNationalsLabel">What is your evaluation of the nationals you are trying to reach, spiritually and culturally?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="evaluationOfNationals" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="timeInCountryLabel">How long have you been in this country?</label>
|
||||
<label class="sub">If you have changed countries, what other countries have you been in and for how long?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<input matInput type="text" placeholder="Your Answer" formControlName="timeInCountry" required>
|
||||
</mat-form-field>
|
||||
<label id="correctWrongOfAnotherMissionaryLabel">If you knew that a fellow missionary was doing wrong or something quesstionable, what would be your course of action?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="correctWrongOfAnotherMissionary" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="financialStatementPrevYearLabel">Would you submit a general financial statement for the past year?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="financialStatementPrevYear" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="currentMonthlySupportLabel">What is your total monthly support (peronal, work fund, etc)?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<input matInput type="text" placeholder="Your Answer" formControlName="currentMonthlySupport" required>
|
||||
</mat-form-field>
|
||||
<label id="monthlySupportNeededLabel">How much monthly support do you calculate you will need?</label>
|
||||
<label class="sub">(We know that there will be differences)</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<input matInput type="text" placeholder="Your Answer" formControlName="monthlySupportNeeded" required>
|
||||
</mat-form-field>
|
||||
<label id="restAndRelaxationLabel">Are you diligent to have "Rest and Relaxation" during your stay on the field? Do you have a set time and plan for such necessary refreshing?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="restAndRelaxation" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="aloneOrTeamLabel">Do you plan to work alone or as a team? What are your feelings about the team concept?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="aloneOrTeam" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="childrenSchoolLabel">Do your children:</label>
|
||||
<label class="sub">Please mark even if your children are yet to be born.</label>
|
||||
<mat-radio-group aria-label="Type of School" formControlName="childrenSchool" aria-labelledby="childrenSchoolLabel">
|
||||
<mat-radio-button class="radio-button" value="1">Attend a Christian School</mat-radio-button>
|
||||
<mat-radio-button class="radio-button" value="2">Attend a Public School</mat-radio-button>
|
||||
<mat-radio-button class="radio-button" value="3">Home School</mat-radio-button>
|
||||
<mat-radio-button class="radio-button" value="4">Other</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="danceLabel">Do you or any of your family ever dance?</label>
|
||||
<mat-radio-group aria-label="Dance" formControlName="dance" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="worldlyMusicLabel">Do you or any of your family ever listen to worldly music in your home?</label>
|
||||
<label class="sub">(Including but not limited to: rock, country/western, r&b, etc.)</label>
|
||||
<mat-radio-group aria-label="Worldy Music" formControlName="worldlyMusic" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="movieTheatersLabel">Do you or any of your family ever attend public movie theaters?</label>
|
||||
<mat-radio-group aria-label="Movie Theaters" formControlName="movieTheaters" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="alcoholLabel">Do you or any of your family ever use any type of alcoholic beverage?</label>
|
||||
<mat-radio-group aria-label="Alcohol" formControlName="alcohol" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="smokingLabel">Do you or any of your family ever engage in any unclean habit such as smoking?</label>
|
||||
<mat-radio-group aria-label="Smoking" formControlName="smoking" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="maleHairLabel">If there are boys in your home, do they follow the same hair standard you follow?</label>
|
||||
<mat-radio-group aria-label="Male Hair" formControlName="maleHair" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="femalSlacksLabel">Does your wife wear slacks in public?</label>
|
||||
<mat-radio-group aria-label="Female Slacks" formControlName="femaleSlacks" class="w-100">
|
||||
<mat-radio-button value="1">Rarely</mat-radio-button>
|
||||
<mat-radio-button value="2">Often</mat-radio-button>
|
||||
<mat-radio-button value="3">On Sports Activities</mat-radio-button>
|
||||
<mat-radio-button value="4">Never</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="femaleShortsLabel">Does your wife wear shorts in public?</label>
|
||||
<mat-radio-group aria-label="Female Shorts" formControlName="femaleShorts" class="w-100">
|
||||
<mat-radio-button value="1">Rarely</mat-radio-button>
|
||||
<mat-radio-button value="2">Often</mat-radio-button>
|
||||
<mat-radio-button value="3">On Sports Activities</mat-radio-button>
|
||||
<mat-radio-button value="4">Never</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="femaleDressStandardLabel">Do the girls in your family follow the same dress standard your wife does?</label>
|
||||
<mat-radio-group aria-label="Female Dress Standard" formControlName="femaleDressStandard" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="swimmingClothingLabel">What do you do for clothing when you go swimming?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="swimmingClothing" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="televisionLabel">How do you feel about having a television in the home?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="television" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="dailyBibleLabel">Do you MAKE time daily for Bible Reading and Prayer?</label>
|
||||
<mat-radio-group aria-labeled-by="dailyBibleLabel" formControlName="dailyBible" class="w-100">
|
||||
<mat-radio-button value="1">Always</mat-radio-button>
|
||||
<mat-radio-button value="2">Sometimes</mat-radio-button>
|
||||
<mat-radio-button value="3">Rarely</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="numberLedToChrist">Outside of the church services where you have ministered, estimate how many people you have personally won to Christ in the last six months.</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<input matInput type="number" placeholder="Your Answer" formControlName="numberLedToChrist" required>
|
||||
</mat-form-field>
|
||||
<label id="numberWitnessedToLabel">How many people have you personally witnessed to?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<input matInput type="number" placeholder="Your Answer" formControlName="numberWitnessedTo" required>
|
||||
</mat-form-field>
|
||||
<label id="numberWeeklyTractsLabel">On average, how many tracts do you pass out in a week?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<input matInput type="number" placeholder="Your Answer" formControlName="numberWeeklyTracts" required>
|
||||
</mat-form-field>
|
||||
<label id="rateOfSuccessLabel">What is your rate of success in fulfilling the great commission, getting your converts baptized and active in the local church where they may be taught?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="rateOfSuccess" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="predestinationLabel">Explain your position briefly concerning predestination and election.</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="predestination" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="fellowshipAssociationLabel">Do you claim identity with any group or fellowship such as BBF, GARB, FBF, Other?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="fellowshipAssociation" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="collegeRecommendationsLabel">To a young person asking you to recommend a Christian College, list two or three Christian Colleges, in order of preference, which you would recommend?</label>
|
||||
<label class="sub">Please list the name, city, and state for each</label>
|
||||
<div *ngIf="form.get('collegeRecommendations').errors?.minColleges && (form.touched || form.dirty)" class="error">
|
||||
{{form.get('collegeRecommendations').errors?.minColleges}}
|
||||
</div>
|
||||
<ol>
|
||||
<li formArrayName="collegeRecommendations" *ngFor="let college of collegeRecommendationFormArray().controls; let i = index;">
|
||||
<div [formGroupName]="i">
|
||||
<mat-form-field floatLabel="never" class="w-100">
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput type="text" formControlName="name">
|
||||
</mat-form-field>
|
||||
<mat-form-field floatLabel="never" class="w-50">
|
||||
<mat-label>City</mat-label>
|
||||
<input matInput type="text" formControlName="city">
|
||||
</mat-form-field>
|
||||
<mat-form-field floatLabel="never" class="w-50">
|
||||
<mat-label>State</mat-label>
|
||||
<input matInput type="text" formControlName="state">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div *ngIf="college.errors?.college && (form.touched || form.dirty)" class="error">
|
||||
{{college.errors?.college}}
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
<label id="admittedWrongLabel">When was the last time you admitted you were wrong about something and apologized?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="admittedWrong" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="divorcedLabel">Have you or your wife ever been divorced?</label>
|
||||
<mat-radio-group formControlName="divorced" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="groundsForRemarryLabel">Do you believe there are grounds whereby a man or women may remarry with a previous spouse still living?</label>
|
||||
<mat-radio-group aria-label="Grounds for Remarry" formControlName="groundsForRemarry" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="marryADivorceeLabel">Have you married a divorced couple or would you?</label>
|
||||
<mat-radio-group aria-label="Married a Divorcee" formControlName="marryADivorcee" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="masonicLodge">Do you believe that being a member of a masonic lodge conflicts with Biblical separation?</label>
|
||||
<mat-radio-group aria-label="Masonic Lodge" formControlName="masonicLodge" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="bibleVersionsUsedLabel">Please list the English version(s) of the Bible you use and approve for preaching and teaching.</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="bibleVersionsUsed" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="bibleVersionOpinionLabel">Please give your opinion of all English versions of the Bible you use and approve for preaching and teaching.</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="bibleVersionOpinion" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="contemporaryMusicLabel">Do you listen to or approve of either "Contemporary Christian Music" or "Gospel rock" music?</label>
|
||||
<mat-radio-group formControlName="contemporaryMusic" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="charasmaticismLabel">What is your position in relation to the modern day Charismatic movement?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="charasmaticism" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="tonguesLabel">Do you or any member of your family speak in tongues?</label>
|
||||
<mat-radio-group formControlName="tongues" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="repentanceNecessaryLabel">Is Repentance a necessary part of salvation?</label>
|
||||
<mat-radio-group formControlName="repentanceNecessary" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="repentanceDefinitionLabel">One definition of repentance is: "Repentance means changing your mind about whatever is keeping you from turning to Jesus."</label>
|
||||
<label class="sub">Do you agree or disagree? Explain your answer.</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="repentanceDefinition" required ></textarea>
|
||||
</mat-form-field>
|
||||
<label id="fundamentalistLabel">Do you consider yourself a fundamentalist?</label>
|
||||
<mat-radio-group formControlName="fundamentalist" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="billsOnTimeLabel">Do you believe it is important to pay your bills on time?</label>
|
||||
<mat-radio-group formControlName="billsOnTime" class="w-100">
|
||||
<mat-radio-button value="true">Yes</mat-radio-button>
|
||||
<mat-radio-button value="false">No</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<label id="lateBillsLabel">How many times in the last 12 months have you been late paying a bill?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="lateBills" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="lateBillActionTakenLabel">What do you do to "make things right" when you are late paying a bill?</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="lateBillActionTaken" required></textarea>
|
||||
</mat-form-field>
|
||||
<label id="potentialHarvestLabel">Though we support Missions and Missionaries doing many things and serving on many fields, we look primarily for Missionaries going to the ripe Harvest fields to begin Churches which will eventually become indigenous Churches. Please evaluate for us the potential of the Harvest field to which you have been called by telling the response of the people at large to Tract or Bible Distribution, Door-to-Door Visitation, and Gospel Preaching.</label>
|
||||
<mat-form-field class="w-100" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="potentialHarvest" required></textarea>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100 hidden" floatLabel="never">
|
||||
<textarea matInput type="text" placeholder="Your Answer" formControlName="honeyPot" required></textarea>
|
||||
</mat-form-field>
|
||||
<button mat-raised-button type="submit" [disabled]="!form.valid || submitButtonDisabled">{{submitButtonText}}</button>
|
||||
<br>
|
||||
<p *ngIf="!form.valid">Please complete all fields to submit</p>
|
||||
</form>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -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<MissionaryFormPageComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ MissionaryFormPageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MissionaryFormPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
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],
|
||||
fellowshipAssociation: ['', Validators.required],
|
||||
collegeRecommendations: 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]
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
hasErrors(formControlName: string): boolean {
|
||||
let res = this.form.get(formControlName) && typeof this.form.get(formControlName).errors !== 'undefined';
|
||||
if (res === true) {
|
||||
res = this.form.get(formControlName).dirty || (this.form.get(formControlName).touched && this.form.get(formControlName).valid === false);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
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:'Missionary Support','message':'Thank You! Your submission has been received.' };
|
||||
let popup = this.matDialog.open(OkPopupComponent,opts);
|
||||
popup.afterClosed().subscribe(()=>{
|
||||
this.submitButtonText = "Form Submitted"
|
||||
});
|
||||
}
|
||||
|
||||
private emailError(){
|
||||
console.error("error");
|
||||
let opts = new MatDialogConfig;
|
||||
opts.data = { title:'Error','message':'Please make sure that you have entered all fields correctly.' };
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +88,8 @@ export class AddSermonPopupComponent implements OnInit {
|
|||
if (this.sermonFile == null){
|
||||
this.errorMessages.push("Please add a sermon MP3 file");
|
||||
}
|
||||
if (this.sermonFile != null && this.sermonFile.type != 'audio/mp3'){
|
||||
if (this.sermonFile != null && this.sermonFile.type != 'audio/mpeg'){
|
||||
|
||||
this.errorMessages.push("File must be a MP3");
|
||||
}
|
||||
if (this.errorMessages.length > 0){ this.updateAddButton(true); return; }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.m-5 {
|
||||
margin: 5px;
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
{{error}}
|
||||
</p>
|
||||
</div>
|
||||
<button mat-raised-button class="first" (click)="cancel($event)" >Cancel</button><!--
|
||||
--><button mat-raised-button type="submit" [disabled]="!addUserForm.form.valid || addUserButtonDisabled">{{ addUserButtonText }}</button>
|
||||
<button mat-raised-button class="first m-5" (click)="cancel($event)" >Cancel</button><!--
|
||||
--><button mat-raised-button class="m-5" type="submit" [disabled]="!addUserForm.form.valid || addUserButtonDisabled">{{ addUserButtonText }}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -30,6 +30,12 @@ export class SharePopupComponent implements OnInit {
|
|||
this.id = data.id;
|
||||
let port = this.document.location.port ? ":"+this.document.location.port : "";
|
||||
this.shareUrl = this.document.location.protocol +'//'+ this.document.location.hostname + port + this.shareBaseUrl + data.prefix + this.id;
|
||||
if (this.data.prefix === 'o') {
|
||||
this.shareUrl = this.document.location.protocol + '//' + this.document.location.hostname + port + this.shareBaseUrl + data.prefix + data.otherName;
|
||||
}
|
||||
if (this.data.url) {
|
||||
this.shareUrl = this.data.url;
|
||||
}
|
||||
this.facebookIframeUrl = this.urlPartA + this.shareUrl + this.urlPartB;
|
||||
this.twitterUrl = this.twitterPartA + data.title + " - " + data.description + "&url=" + this.shareUrl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
iframe {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
display: inline-block;
|
||||
margin-bottom: 15px;
|
||||
width: calc(100% - 50px);
|
||||
}
|
||||
|
||||
hr{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 24pt;
|
||||
|
||||
}
|
||||
|
||||
.vertical-align-top {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<div md-dialog-title>
|
||||
<h2>{{title}}</h2>
|
||||
<button mat-icon-button (click)="close()">
|
||||
<i ofbicon>close</i>
|
||||
</button>
|
||||
</div>
|
||||
<hr color="primary">
|
||||
<div md-dialog-content>
|
||||
<iframe width="560" height="315" [src]="embedUrl | safeUrl" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { YoutubePopupComponent } from './youtube-popup.component';
|
||||
|
||||
describe('YoutubePopupComponent', () => {
|
||||
let component: YoutubePopupComponent;
|
||||
let fixture: ComponentFixture<YoutubePopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ YoutubePopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(YoutubePopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector: 'app-youtube-popup',
|
||||
templateUrl: './youtube-popup.component.html',
|
||||
styleUrls: ['./youtube-popup.component.css']
|
||||
})
|
||||
export class YoutubePopupComponent implements OnInit {
|
||||
|
||||
public title: string;
|
||||
public embedUrl: string;
|
||||
|
||||
constructor(@Inject(MAT_DIALOG_DATA) public data: any, private MatDialogRef: MatDialogRef<YoutubePopupComponent>) {
|
||||
this.title = data.title;
|
||||
this.embedUrl = data.embedUrl;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
public close() {
|
||||
this.MatDialogRef.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
<div class="description">{{ description }}</div><!--
|
||||
--><div class="action-buttons">
|
||||
<button mat-button class="action pct40" (click)="play()" ><i ofbicon>headset</i> Listen</button><!--
|
||||
--><button mat-button class="action pct50" (click)="download()" ><i ofbicon>file_download</i> Download</button><!--
|
||||
--><a download="{{title}}" href="{{url}}" mat-button class="action pct50" ><i ofbicon>file_download</i> Download</a><!--
|
||||
--><button mat-button class="action pct10" (click)="share()" ><i ofbicon>share</i> Share</button>
|
||||
</div><!--
|
||||
--><div class="action-buttons" *ngIf="loggedIn">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
.wrapper{
|
||||
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||
}
|
||||
|
||||
.photo{
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
max-width: 180px;
|
||||
margin: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.fade{
|
||||
text-align: center;
|
||||
vertical-align: bottom;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 20px;
|
||||
padding-bottom: 2px;
|
||||
/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ffffff+100&0+0,0.8+100 */
|
||||
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,0.8) 100%); /* FF3.6-15 */
|
||||
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,0.8) 100%); /* Chrome10-25,Safari5.1-6 */
|
||||
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,0.8) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ccffffff',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
|
||||
.photo button{
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
button img{
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.info{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 2px 2px 8px 5px;
|
||||
box-sizing: border-box;
|
||||
width: calc(100% - 180px);
|
||||
overflow-y: hidden;
|
||||
position: relative;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.title{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.date, .author{
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.description{
|
||||
font-size: 14px;
|
||||
color: darkgray;
|
||||
word-wrap: none;
|
||||
border-top: 0px solid lightgray;
|
||||
padding-top:6px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.expanded{
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.expanded-content{
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.buttons, .buttons-edit{
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.buttons button, .buttons .filler{
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.border{
|
||||
margin: 0px 5px 0px 5px;
|
||||
border-top: 1px inset lightgray;
|
||||
}
|
||||
|
||||
.buttons-edit button{
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<div class="wrapper" [@inout]="startFadeIn">
|
||||
<div class="photo">
|
||||
<button mat-button (click)="play()">
|
||||
<img src="{{thumbnailUrl}}" />
|
||||
</button>
|
||||
</div><!--
|
||||
--><div class="info" (click)="toggleState()">
|
||||
<span class="title">{{ title }}</span>
|
||||
<br>
|
||||
<span class="date">{{ publishTime | ofbDate:true }}</span>
|
||||
<br>
|
||||
<p class="description" [@toggleAnimationFade]="state">
|
||||
{{ description }}
|
||||
</p>
|
||||
<div class="fade"><i ofbicon *ngIf="state === 'closed'">arrow_drop_down</i><i ofbicon *ngIf="state === 'open'">arrow_drop_up</i></div>
|
||||
</div>
|
||||
<div class="expanded" [@toggleAnimation]="state" (click)="toggleState()">
|
||||
<p class="expanded-content">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<button mat-button class="action pct50" (click)="play()" ><i ofbicon>tv</i> Play</button><!--
|
||||
--><button mat-button class="action pct50" (click)="share()" ><i ofbicon>share</i> Share</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { VideoItemComponent } from './video-item.component';
|
||||
|
||||
describe('VideoItemComponent', () => {
|
||||
let component: VideoItemComponent;
|
||||
let fixture: ComponentFixture<VideoItemComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ VideoItemComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(VideoItemComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import { Component, AfterContentInit, Input, Inject } from '@angular/core';
|
||||
import { MatDialog, MatDialogConfig } from '@angular/material';
|
||||
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||
|
||||
import { SharePopupComponent } from './../popups/share-popup/share-popup.component';
|
||||
import { YesNoPopupComponent } from './../popups/yes-no-popup/yes-no-popup.component';
|
||||
import { YoutubePopupComponent } from '../popups/youtube-popup/youtube-popup.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-video-item',
|
||||
templateUrl: './video-item.component.html',
|
||||
styleUrls: ['./video-item.component.css'],
|
||||
animations:[
|
||||
trigger("inout",[
|
||||
state("1", style({ opacity: '1' })),
|
||||
state("0",style({ opacity: '0' })),
|
||||
transition('* => 1',[
|
||||
animate('500ms ease-in-out')
|
||||
]),
|
||||
transition(':enter',[
|
||||
animate('0ms')
|
||||
])
|
||||
]),
|
||||
trigger('toggleAnimation', [
|
||||
state('open', style({
|
||||
height: '*',
|
||||
})),
|
||||
state('closed', style({
|
||||
height: '0px',
|
||||
})),
|
||||
transition('open <=> closed', animate('500ms ease-in-out'))
|
||||
]),
|
||||
trigger('toggleAnimationFade', [
|
||||
state('open', style({
|
||||
opacity: 0,
|
||||
})),
|
||||
state('closed', style({
|
||||
opacity: 1,
|
||||
})),
|
||||
transition('open <=> closed', animate('500ms ease-in-out'))
|
||||
])
|
||||
]
|
||||
})
|
||||
export class VideoItemComponent implements AfterContentInit {
|
||||
|
||||
public state: string = 'closed';
|
||||
|
||||
@Input()
|
||||
id: number;
|
||||
@Input()
|
||||
title: string;
|
||||
@Input()
|
||||
description: string;
|
||||
@Input()
|
||||
publishTime: Date;
|
||||
@Input()
|
||||
thumbnailUrl: string;
|
||||
@Input()
|
||||
shareUrl: string;
|
||||
@Input()
|
||||
embedUrl: string;
|
||||
public startFadeIn: boolean = false;
|
||||
@Input()
|
||||
public delayFadeIn: number = 100;
|
||||
|
||||
constructor(private dialog: MatDialog){
|
||||
}
|
||||
|
||||
ngAfterContentInit(): void{
|
||||
setTimeout(() => this.startFadeIn = true, this.delayFadeIn);
|
||||
}
|
||||
|
||||
toggleState(){
|
||||
this.state = this.state === 'open' ? 'closed' : 'open'
|
||||
}
|
||||
|
||||
share(){
|
||||
let opts = new MatDialogConfig;
|
||||
opts.data = { url: this.shareUrl, id: this.id, title: this.title, description: '' };
|
||||
let dialog = this.dialog.open(SharePopupComponent, opts);
|
||||
}
|
||||
|
||||
play(){
|
||||
let opts = new MatDialogConfig;
|
||||
opts.data = { title: this.title, embedUrl:this.embedUrl };
|
||||
let dialog = this.dialog.open(YoutubePopupComponent, opts);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
.yt-container {
|
||||
position: relative;
|
||||
padding-bottom: 56.25%; /* 16:9 */
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.yt-container iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<div *ngFor="let video of services; let i = index;" style="margin-top: 10px;">
|
||||
<button (click)="showVideo(i)" mat-stroked-button style="margin-bottom: 10px;">
|
||||
<i ofbicon class="mr-10" >live_tv</i>
|
||||
{{getTitle(i)}}
|
||||
</button>
|
||||
<div *ngIf="video.show && video.yt" class="yt-container">
|
||||
<iframe [src]="video.yt | safeUrl" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
<video style="width:100%" *ngIf="video.show && !video.yt" src="{{video.src}}" controls poster="https://ofbbutte.com/static/media/video/ClickToPlay.jpg"></video>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import { WindowRefService } from './../../services/window-ref.service';
|
||||
import { Component, HostListener, OnInit } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { VideoServices, VideoService } from '../home/video-services';
|
||||
import { DateTime } from "luxon";
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'video-services-component',
|
||||
templateUrl: './video-services.component.html',
|
||||
styleUrls: ['./video-services.component.css'],
|
||||
})
|
||||
export class VideoServicesComponent implements OnInit {
|
||||
|
||||
public loading: boolean = true;
|
||||
public services: VideoService[];
|
||||
|
||||
constructor(private http: HttpClient){ }
|
||||
|
||||
ngOnInit(){
|
||||
this.http.get<VideoServices>('assets/json/videoServices.json')
|
||||
.subscribe(res => {
|
||||
this.services = res.videos.filter(v => v.isReady === true);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
showVideo(index: number) {
|
||||
this.services.forEach(s => {
|
||||
(<any>s).show = false;
|
||||
});
|
||||
(<any>this.services[index]).show = true;
|
||||
}
|
||||
|
||||
getTitle(index: number): string {
|
||||
const title = this.services[index].title;
|
||||
const dte = DateTime.fromISO(this.services[index].date, {zone: 'America/Denver'})
|
||||
return title + ' | ' + dte.toLocaleString(DateTime.DATETIME_MED);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
|
||||
.side-bar{
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.width100{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#showAllButton{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<app-youtube-list></app-youtube-list>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { VideoComponent } from './video.component';
|
||||
|
||||
describe('VideoComponent', () => {
|
||||
let component: VideoComponent;
|
||||
let fixture: ComponentFixture<VideoComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ VideoComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(VideoComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-video',
|
||||
templateUrl: './video.component.html',
|
||||
styleUrls: ['./video.component.css']
|
||||
})
|
||||
export class VideoComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -91,6 +91,6 @@ p.margin-bottom {
|
|||
|
||||
@media(max-width: 450px) {
|
||||
.float-left {
|
||||
width: 175px
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,9 +17,10 @@
|
|||
<img class="image shadow container-3-col" src="assets/images/home-images/tiny/church.jpg" alt="Church Image" />
|
||||
</div>
|
||||
<br><br>
|
||||
|
||||
<p ofbFadeInOnScroll class="section-header">Pastor Derek Loewen</p>
|
||||
<div ofbFadeInOnScroll class="section-paragraph overflow-hidden">
|
||||
<img class="float-left margin-right-10 border-radius-5" src="assets/images/tiny/pstr.jpg" alt="Pastor Photo" width="225px" />
|
||||
<img class="float-left margin-right-10 border-radius-5" src="assets/images/tiny/pstr3.jpg" alt="Pastor Photo" width="350px" />
|
||||
<p class="margin-bottom">
|
||||
Pastor Derek Loewen heard the gospel for the first time when a friend invited him to
|
||||
Florence Baptist Church in Florence, Montana. They rode the bus to Sunday School.
|
||||
|
|
@ -29,10 +30,10 @@
|
|||
</p>
|
||||
<p class="margin-bottom">
|
||||
During his senior year of high school, Pastor Loewen yielded his life to the Lord.
|
||||
Upon graduation from Crown College of the Bible in 2003, he served in the church he
|
||||
Upon graduation from Bible College in 2003, he served in the church he
|
||||
was saved in as a young boy before marrying his bride, Rebecca in June 2004.
|
||||
The Lord has graciously allowed them to serve Him together across the country both
|
||||
assisting pastors and planting a church. God has blessed their home with 3 delightful
|
||||
assisting pastors and planting a church. God has blessed their home with 5 delightful
|
||||
children.
|
||||
</p>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { YoutubeSearchResult } from './youtube-snippet';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
const apiKey = 'AIzaSyDYI1UzFyc-5UvWiN7BqkWm-8vXU6i5Au0';
|
||||
const baseUrl = `https://www.googleapis.com/youtube/v3/search`;
|
||||
const part = `snippet`;
|
||||
const channelId = `UCplK-bimKe_E8k6Gka87IaQ`;
|
||||
const maxResults = `20`;
|
||||
const order = `date`;
|
||||
const itemType = `video`;
|
||||
|
||||
@Injectable()
|
||||
export class YoutubeListService {
|
||||
constructor(private httpClient: HttpClient){}
|
||||
private nextPageToken: string;
|
||||
|
||||
public getFirstPage() : Observable<YoutubeSearchResult> {
|
||||
const url = this.getUrl(undefined);
|
||||
return this.httpClient.get<YoutubeSearchResult>(url).pipe(tap(x => this.nextPageToken = x.nextPageToken));
|
||||
}
|
||||
|
||||
public getNextPage() : Observable<YoutubeSearchResult> {
|
||||
const url = this.getUrl(this.nextPageToken);
|
||||
return this.httpClient.get<YoutubeSearchResult>(url).pipe(tap(x => this.nextPageToken = x.nextPageToken));
|
||||
}
|
||||
|
||||
private getUrl(nextPageToken: string): string {
|
||||
let url = `${baseUrl}?type=${itemType}&part=${part}&channelId=${channelId}&maxResults=${maxResults}&order=${order}&key=${apiKey}`;
|
||||
if (nextPageToken) {
|
||||
url = url + `&pageToken=${nextPageToken}`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
.width100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mt-20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
ul{
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li{
|
||||
margin: 40px 0px 40px 0px; /* top right bottom left */
|
||||
}
|
||||
|
||||
li:first-child{
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
li:last-child{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
|
||||
|
||||
|
||||
<ul>
|
||||
<li *ngFor="let item of items">
|
||||
<app-video-item
|
||||
[title]="item.snippet.title"
|
||||
[description]="item.snippet.description"
|
||||
[publishTime]="item.snippet.publishTime"
|
||||
[thumbnailUrl]="item.snippet.thumbnails.medium.url"
|
||||
shareUrl="https://youtu.be/{{item.id.videoId}}"
|
||||
embedUrl="https://www.youtube.com/embed/{{item.id.videoId}}">
|
||||
|
||||
</app-video-item>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button *ngIf="showLoadMore()" mat-button [disabled]="loading" class="width100 mt-20" style="text-align: center;" (click)="loadMore()">
|
||||
<i ofbicon *ngIf="loading">access_time</i><span *ngIf="loading"> Loading...</span>
|
||||
<i ofbicon *ngIf="!loading">expand_more</i><span *ngIf="!loading"> Load More</span>
|
||||
</button>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { YoutubeListComponent } from './youtube-list.component';
|
||||
|
||||
describe('YoutubeListComponent', () => {
|
||||
let component: YoutubeListComponent;
|
||||
let fixture: ComponentFixture<YoutubeListComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ YoutubeListComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(YoutubeListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { YoutubeListService } from './youtube-list-service';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { YoutubeSnippet, YoutubeSnippetItem, YoutubeSearchResult } from './youtube-snippet';
|
||||
|
||||
@Component({
|
||||
selector: 'app-youtube-list',
|
||||
templateUrl: './youtube-list.component.html',
|
||||
styleUrls: ['./youtube-list.component.css']
|
||||
})
|
||||
export class YoutubeListComponent implements OnInit {
|
||||
public loading: boolean = false;
|
||||
public items: YoutubeSnippetItem[] = [];
|
||||
private totalResults: number = 0;
|
||||
|
||||
constructor(private youtube: YoutubeListService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.loading = true;
|
||||
this.youtube.getFirstPage().pipe(take(1)).subscribe(x => {
|
||||
this.totalResults = x.pageInfo.totalResults;
|
||||
this.processResults(x);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
public showLoadMore() {
|
||||
if (this.items.length < this.totalResults && this.loading === false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public loadMore() {
|
||||
if (this.items.length >= this.totalResults) {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
this.youtube.getNextPage().pipe(take(1)).subscribe(x => {
|
||||
this.processResults(x);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
private processResults(res: YoutubeSearchResult) {
|
||||
var parser = new DOMParser;
|
||||
res.items.forEach(x => x.snippet.title = parser.parseFromString(x.snippet.title, "text/html").body.innerHTML);
|
||||
if (this.items.length === 0) {
|
||||
this.items = res.items;
|
||||
} else {
|
||||
for(let i = 0; i < res.items.length; i++) {
|
||||
this.items.push(res.items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
export class YoutubeSearchResult {
|
||||
public kind: string;
|
||||
public etag: string;
|
||||
public nextPageToken: string;
|
||||
public regionCode: string;
|
||||
public pageInfo: YoutubeSearchResultPageInfo;
|
||||
public items: YoutubeSnippetItem[];
|
||||
}
|
||||
|
||||
export class YoutubeSearchResultPageInfo {
|
||||
public totalResults: number;
|
||||
public resultsPerPage: number;
|
||||
}
|
||||
|
||||
export class YoutubeSnippetItem {
|
||||
public kind: string;
|
||||
public etag: string;
|
||||
public id: YoutubeSnippetId;
|
||||
public snippet: YoutubeSnippet
|
||||
}
|
||||
|
||||
export class YoutubeSnippetId {
|
||||
public kind: string;
|
||||
public videoId: string;
|
||||
}
|
||||
|
||||
export class YoutubeSnippet {
|
||||
public publishedAt: Date;
|
||||
public channelId: string;
|
||||
public title: string;
|
||||
public description: string;
|
||||
public channelTitle: string;
|
||||
public liveBroadcastContent: string;
|
||||
public publishTime: Date;
|
||||
public thumbnails: YoutubeSnippetThumbnails;
|
||||
}
|
||||
|
||||
export class YoutubeSnippetThumbnails {
|
||||
public default: YoutubeThumbnail;
|
||||
public medium: YoutubeThumbnail;
|
||||
public high: YoutubeThumbnail;
|
||||
}
|
||||
|
||||
export class YoutubeThumbnail {
|
||||
public url: string;
|
||||
public width: number;
|
||||
public height: number;
|
||||
}
|
||||
|
|
@ -4,15 +4,17 @@ 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.baseApi + "/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';
|
||||
export const SERMON_MP3_BASE_URL = '//ofbbutte.com/static/media/';
|
||||
export const SERMON_MP3_BASE_URL = '/media/';
|
||||
export const SERMON_ADD_URL = environment.baseUrl + "/api2/sermons/a/";
|
||||
export const SERMON_DELETE_URL = environment.baseUrl + "/api2/sermons/a/";
|
||||
export const SERMON_UPDATE_URL = environment.baseUrl + "/api2/sermons/a/";
|
||||
export const SERMON_DOWNLOAD_URL = environment.baseUrl + "/api2/sermons/download/";
|
||||
export const TRANSACTION_CREATE_URL = environment.baseUrl + "/api2/transactions/a/";
|
||||
export const TRANSACTION_GET_BY_YEAR_URL = environment.baseUrl + "/api2/transactions/a/";
|
||||
export const USER_CREATE_URL = environment.baseUrl + "/api2/users/a/";
|
||||
export const USER_GET_ALL_URL = environment.baseUrl + "/api2/users/a";
|
||||
export const LOGIN_URL = environment.baseUrl + '/api2/login';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
export const ICONS = {
|
||||
access_time: '',
|
||||
add: '',
|
||||
announcement: '',
|
||||
close: '',
|
||||
copyright: '',
|
||||
delete_forever: '',
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ export class OfbDatePipe implements PipeTransform {
|
|||
console.error("value for ofb-date-pipe was undefined or null");
|
||||
return value;
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
value = new Date(value);
|
||||
}
|
||||
var year = value.getFullYear();
|
||||
var month = value.getMonth() + 1;
|
||||
var day = value.getDate();
|
||||
|
|
|
|||
|
|
@ -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.');
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class PrintService {
|
||||
|
||||
public isPrinting: boolean = false;
|
||||
|
||||
constructor(){}
|
||||
|
||||
public setPrinting(printing: boolean) {
|
||||
this.isPrinting = printing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4,7 +4,7 @@ import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
|||
import { Observable, Subject, throwError, of } from 'rxjs';
|
||||
import { catchError, map, tap, first } from 'rxjs/operators';
|
||||
|
||||
import { TRANSACTION_CREATE_URL } from '../constants/urls';
|
||||
import { TRANSACTION_CREATE_URL, TRANSACTION_GET_BY_YEAR_URL } from '../constants/urls';
|
||||
import { Transaction } from '../components/add-transaction-page/transaction';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -41,6 +41,11 @@ export class TransactionService {
|
|||
.pipe(tap(res => console.log(res)), catchError(this.handleError));
|
||||
}
|
||||
|
||||
getByYear(taxYear: number) {
|
||||
return this.httpClient.get(TRANSACTION_GET_BY_YEAR_URL + "?taxYear=" + taxYear, this.options)
|
||||
.pipe(catchError(this.handleError));
|
||||
}
|
||||
|
||||
private handleError(error: HttpErrorResponse) {
|
||||
if (error.error instanceof ErrorEvent) {
|
||||
// A client-side or network error occurred. Handle it accordingly.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export class UserService {
|
|||
|
||||
getAll(){
|
||||
return this.httpClient.get(USER_GET_ALL_URL, this.options)
|
||||
.pipe(tap(res => console.log(res)), catchError(this.handleError));
|
||||
.pipe(catchError(this.handleError));
|
||||
}
|
||||
|
||||
create(firstName: string, lastName: string, street: string, city: string, state: string, zip: string, country: string) {
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 6.7 MiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 5.8 MiB |
|
After Width: | Height: | Size: 46 KiB |