Update to Angular 7
commit
438fef27a0
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Editor configuration, see https://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# profiling files
|
||||||
|
chrome-profiler-events.json
|
||||||
|
speed-measure-plugin.json
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.history/*
|
||||||
|
|
||||||
|
# misc
|
||||||
|
/.sass-cache
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
|
# System Files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Ofbclient
|
||||||
|
|
||||||
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.2.
|
||||||
|
|
||||||
|
## Development server
|
||||||
|
|
||||||
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||||
|
|
||||||
|
## Code scaffolding
|
||||||
|
|
||||||
|
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||||
|
|
||||||
|
## Running end-to-end tests
|
||||||
|
|
||||||
|
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||||
|
|
||||||
|
## Further help
|
||||||
|
|
||||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"ofbclient": {
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"projectType": "application",
|
||||||
|
"prefix": "app",
|
||||||
|
"schematics": {},
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "../Server/www",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"main": "src/main.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets",
|
||||||
|
"src/web-app-files"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"src/styles.css"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": false,
|
||||||
|
"extractCss": true,
|
||||||
|
"namedChunks": false,
|
||||||
|
"aot": true,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "2mb",
|
||||||
|
"maximumError": "5mb"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "ofbclient:build"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"browserTarget": "ofbclient:build:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "ofbclient:build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "src/test.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
|
"karmaConfig": "src/karma.conf.js",
|
||||||
|
"styles": [
|
||||||
|
"src/styles.css"
|
||||||
|
],
|
||||||
|
"scripts": [],
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": [
|
||||||
|
"src/tsconfig.app.json",
|
||||||
|
"src/tsconfig.spec.json"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ofbclient-e2e": {
|
||||||
|
"root": "e2e/",
|
||||||
|
"projectType": "application",
|
||||||
|
"prefix": "",
|
||||||
|
"architect": {
|
||||||
|
"e2e": {
|
||||||
|
"builder": "@angular-devkit/build-angular:protractor",
|
||||||
|
"options": {
|
||||||
|
"protractorConfig": "e2e/protractor.conf.js",
|
||||||
|
"devServerTarget": "ofbclient:serve"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"devServerTarget": "ofbclient:serve:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultProject": "ofbclient"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Protractor configuration file, see link for more information
|
||||||
|
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||||
|
|
||||||
|
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
allScriptsTimeout: 11000,
|
||||||
|
specs: [
|
||||||
|
'./src/**/*.e2e-spec.ts'
|
||||||
|
],
|
||||||
|
capabilities: {
|
||||||
|
'browserName': 'chrome'
|
||||||
|
},
|
||||||
|
directConnect: true,
|
||||||
|
baseUrl: 'http://localhost:4200/',
|
||||||
|
framework: 'jasmine',
|
||||||
|
jasmineNodeOpts: {
|
||||||
|
showColors: true,
|
||||||
|
defaultTimeoutInterval: 30000,
|
||||||
|
print: function() {}
|
||||||
|
},
|
||||||
|
onPrepare() {
|
||||||
|
require('ts-node').register({
|
||||||
|
project: require('path').join(__dirname, './tsconfig.e2e.json')
|
||||||
|
});
|
||||||
|
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { AppPage } from './app.po';
|
||||||
|
import { browser, logging } from 'protractor';
|
||||||
|
|
||||||
|
describe('workspace-project App', () => {
|
||||||
|
let page: AppPage;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
page = new AppPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display welcome message', () => {
|
||||||
|
page.navigateTo();
|
||||||
|
expect(page.getTitleText()).toEqual('Welcome to ofbclient!');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
// Assert that there are no errors emitted from the browser
|
||||||
|
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
||||||
|
expect(logs).not.toContain(jasmine.objectContaining({
|
||||||
|
level: logging.Level.SEVERE,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { browser, by, element } from 'protractor';
|
||||||
|
|
||||||
|
export class AppPage {
|
||||||
|
navigateTo() {
|
||||||
|
return browser.get('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
getTitleText() {
|
||||||
|
return element(by.css('app-root h1')).getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/app",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"jasminewd2",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,51 @@
|
||||||
|
{
|
||||||
|
"name": "ofbclient",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve",
|
||||||
|
"build": "ng build",
|
||||||
|
"test": "ng test",
|
||||||
|
"lint": "ng lint",
|
||||||
|
"e2e": "ng e2e"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/animations": "^7.2.1",
|
||||||
|
"@angular/cdk": "^7.2.1",
|
||||||
|
"@angular/common": "~7.2.0",
|
||||||
|
"@angular/compiler": "~7.2.0",
|
||||||
|
"@angular/core": "~7.2.0",
|
||||||
|
"@angular/forms": "~7.2.0",
|
||||||
|
"@angular/material": "^7.2.1",
|
||||||
|
"@angular/platform-browser": "~7.2.0",
|
||||||
|
"@angular/platform-browser-dynamic": "~7.2.0",
|
||||||
|
"@angular/router": "~7.2.0",
|
||||||
|
"core-js": "^2.5.4",
|
||||||
|
"hammerjs": "^2.0.8",
|
||||||
|
"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/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",
|
||||||
|
"codelyzer": "~4.5.0",
|
||||||
|
"jasmine-core": "~2.99.1",
|
||||||
|
"jasmine-spec-reporter": "~4.2.1",
|
||||||
|
"karma": "~3.1.1",
|
||||||
|
"karma-chrome-launcher": "~2.2.0",
|
||||||
|
"karma-coverage-istanbul-reporter": "~2.0.1",
|
||||||
|
"karma-jasmine": "~1.1.2",
|
||||||
|
"karma-jasmine-html-reporter": "^0.2.2",
|
||||||
|
"protractor": "~5.4.0",
|
||||||
|
"ts-node": "~7.0.0",
|
||||||
|
"tslint": "~5.11.0",
|
||||||
|
"typescript": "~3.2.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
|
//Components
|
||||||
|
import { HomeComponent } from './components/home/home.component';
|
||||||
|
import { WhoWeAreComponent } from './components/whoweare/whoweare.component';
|
||||||
|
import { ServicesComponent } from './components/services/services.component';
|
||||||
|
import { SermonsComponent } from './components/sermons/sermons.component';
|
||||||
|
import { LocationComponent } from './components/location/location.component';
|
||||||
|
import { EventsPageComponent } from './components/events-page/events-page.component';
|
||||||
|
import { ContactPageComponent } from './components/contact-page/contact-page.component';
|
||||||
|
import { SalvationPageComponent } from './components/salvation-page/salvation-page.component';
|
||||||
|
|
||||||
|
const routes =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
redirectTo: '/home',
|
||||||
|
pathMatch: 'full'
|
||||||
|
},{
|
||||||
|
path: 'home',
|
||||||
|
component: HomeComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'whoweare',
|
||||||
|
component: WhoWeAreComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'services',
|
||||||
|
component: ServicesComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'contact',
|
||||||
|
component: ContactPageComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'sermons',
|
||||||
|
component: SermonsComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'sermons/:id',
|
||||||
|
component: SermonsComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'location',
|
||||||
|
component: LocationComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'events',
|
||||||
|
component: EventsPageComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'events/:id',
|
||||||
|
component: EventsPageComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'salvation',
|
||||||
|
component: SalvationPageComponent
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forRoot(routes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class AppRoutingModule { }
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
import { EventService } from './services/event.service';
|
||||||
|
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 { LoginService } from './services/login.service';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { MatButtonModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatSliderModule,
|
||||||
|
MatSnackBarModule,
|
||||||
|
MatDialogModule } from '@angular/material';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import 'hammerjs';
|
||||||
|
|
||||||
|
//Components
|
||||||
|
import { AppComponent } from './components/app/app.component';
|
||||||
|
import { MenuComponent } from './components/menu/menu.component';
|
||||||
|
import { IconButtonComponent } from './components/icon-button/icon-button.component';
|
||||||
|
import { HomeComponent } from './components/home/home.component';
|
||||||
|
import { WhoWeAreComponent } from './components/whoweare/whoweare.component';
|
||||||
|
import { ServicesComponent } from './components/services/services.component';
|
||||||
|
import { SecondaryPageComponent } from './components/secondary-page/secondary-page.component';
|
||||||
|
import { RecentSermonsComponent } from './components/recent-sermons/recent-sermons.component';
|
||||||
|
import { SermonSmallComponent } from './components/sermon-small/sermon-small.component';
|
||||||
|
import { DateComponent } from './components/date/date.component';
|
||||||
|
import { UpcomingEventsComponent } from './components/upcoming-events/upcoming-events.component';
|
||||||
|
import { EventComponent } from './components/event/event.component';
|
||||||
|
import { SermonsComponent } from './components/sermons/sermons.component';
|
||||||
|
import { AudioPlayerComponent } from './components/audio-player/audio-player.component';
|
||||||
|
import { LocationComponent } from './components/location/location.component';
|
||||||
|
import { SermonLargeComponent } from './components/sermon-large/sermon-large.component';
|
||||||
|
import { AddSermonPopupComponent } from './components/popups/add-sermon-popup/add-sermon-popup.component';
|
||||||
|
import { LoginPopupComponent } from './components/popups/login-popup/login-popup.component';
|
||||||
|
import { InputPopupComponent } from './components/popups/input-popup/input-popup.component';
|
||||||
|
import { EventsPageComponent } from './components/events-page/events-page.component';
|
||||||
|
import { AddEventPopupComponent } from './components/popups/add-event-popup/add-event-popup.component';
|
||||||
|
import { OkPopupComponent } from './components/popups/ok-popup/ok-popup.component';
|
||||||
|
import { YesNoPopupComponent } from './components/popups/yes-no-popup/yes-no-popup.component';
|
||||||
|
import { UpdateSermonPopupComponent } from './components/popups/update-sermon-popup/update-sermon-popup.component';
|
||||||
|
import { ContactPageComponent } from './components/contact-page/contact-page.component';
|
||||||
|
import { SharePopupComponent } from './components/popups/share-popup/share-popup.component';
|
||||||
|
import { EventLargeComponent } from './components/event-large/event-large.component';
|
||||||
|
import { SalvationPageComponent } from './components/salvation-page/salvation-page.component';
|
||||||
|
|
||||||
|
//Directives
|
||||||
|
import { FadeInOnScrollDirective } from './directives/fade-in-on-scroll.directive';
|
||||||
|
import { IconDirective } from './directives/icon.directive';
|
||||||
|
|
||||||
|
//Pipes
|
||||||
|
import { DurationPipe } from './pipes/duration.pipe';
|
||||||
|
import { SafeUrlPipe } from './pipes/safe-url.pipe';
|
||||||
|
import { OfbDatePipe } from './pipes/ofb-date.pipe';
|
||||||
|
|
||||||
|
// Routing
|
||||||
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
MenuComponent,
|
||||||
|
IconButtonComponent,
|
||||||
|
HomeComponent,
|
||||||
|
WhoWeAreComponent,
|
||||||
|
ServicesComponent,
|
||||||
|
FadeInOnScrollDirective,
|
||||||
|
IconDirective,
|
||||||
|
SecondaryPageComponent,
|
||||||
|
RecentSermonsComponent,
|
||||||
|
SermonSmallComponent,
|
||||||
|
DateComponent,
|
||||||
|
UpcomingEventsComponent,
|
||||||
|
EventComponent,
|
||||||
|
SermonsComponent,
|
||||||
|
AudioPlayerComponent,
|
||||||
|
DurationPipe,
|
||||||
|
LocationComponent,
|
||||||
|
SermonLargeComponent,
|
||||||
|
AddSermonPopupComponent,
|
||||||
|
LoginPopupComponent,
|
||||||
|
OkPopupComponent,
|
||||||
|
InputPopupComponent,
|
||||||
|
YesNoPopupComponent,
|
||||||
|
UpdateSermonPopupComponent,
|
||||||
|
ContactPageComponent,
|
||||||
|
SharePopupComponent,
|
||||||
|
SafeUrlPipe,
|
||||||
|
EventsPageComponent,
|
||||||
|
AddEventPopupComponent,
|
||||||
|
EventLargeComponent,
|
||||||
|
OfbDatePipe,
|
||||||
|
SalvationPageComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
FormsModule,
|
||||||
|
HttpClientModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
//Angular Material Components
|
||||||
|
MatButtonModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatSliderModule,
|
||||||
|
MatSnackBarModule,
|
||||||
|
MatDialogModule,
|
||||||
|
],
|
||||||
|
providers: [LoginService,GoogleAnalyticsService,SermonService,EventService,EmailService,WindowRefService],
|
||||||
|
entryComponents: [AddSermonPopupComponent,
|
||||||
|
LoginPopupComponent,
|
||||||
|
OkPopupComponent,
|
||||||
|
InputPopupComponent,
|
||||||
|
YesNoPopupComponent,
|
||||||
|
UpdateSermonPopupComponent,
|
||||||
|
SharePopupComponent,
|
||||||
|
AddEventPopupComponent],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
|
||||||
|
|
||||||
|
header{
|
||||||
|
position:fixed;
|
||||||
|
top:0;
|
||||||
|
left:0;
|
||||||
|
width:100%;
|
||||||
|
height: 50px;
|
||||||
|
color: white;
|
||||||
|
vertical-align: middle;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header-background{
|
||||||
|
background-color: rgb(0, 188, 212);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
box-shadow: 0 2px 5px 0 rgba(0,0,0,0.24);
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo{
|
||||||
|
margin-left: -5px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-menu-button{
|
||||||
|
float: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hideOnMobile{
|
||||||
|
display:inline-block;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.header-button, .header-button-home{
|
||||||
|
height: 100%;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.content{
|
||||||
|
margin-top: 50px;
|
||||||
|
min-height: 100%;
|
||||||
|
margin-bottom: -140px;
|
||||||
|
padding-bottom: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer{
|
||||||
|
background-color: rgb(50,50,50);
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
height: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer-content{
|
||||||
|
margin: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-panel{
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: calc(33% - 20px);
|
||||||
|
margin: 10px;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media(max-width: 900px){
|
||||||
|
.header-button, .hideOnMobile{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: 800px){
|
||||||
|
footer{
|
||||||
|
height: 380px;
|
||||||
|
}
|
||||||
|
.footer-panel{
|
||||||
|
display: block;
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
}
|
||||||
|
.content{
|
||||||
|
margin-bottom: -380px;
|
||||||
|
padding-bottom: 380px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright{
|
||||||
|
font-size: 18px;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
a{
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited{
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-player-filler{
|
||||||
|
height: 70px;
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-player{
|
||||||
|
position: fixed;
|
||||||
|
bottom: -65px;
|
||||||
|
width: 100%;
|
||||||
|
height: 65px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: rgb(100,100,100);
|
||||||
|
box-shadow: 0 -2px 5px 0 rgba(0,0,0,0.24);
|
||||||
|
background-color: rgb(100,100,100);
|
||||||
|
color: white;
|
||||||
|
transition: .5s ease-in-out bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-player-slide-up{
|
||||||
|
bottom:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio-player-component{
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: auto;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<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>
|
||||||
|
<button mat-button class="header-button" routerLink="/whoweare">Who We Are</button>
|
||||||
|
<button mat-button class="header-button" routerLink="/services">Service Times</button>
|
||||||
|
<button mat-button class="header-button" routerLink="/location">Location</button>
|
||||||
|
<button mat-button class="header-button" routerLink="/sermons">Sermons</button>
|
||||||
|
<button mat-icon-button id="main-menu-button"
|
||||||
|
(click)="mainMenuClick()">
|
||||||
|
<i ofbicon class="example-icon" style="line-height:20px;">menu</i>
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<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">
|
||||||
|
<p>5003 Wynne Ave</p>
|
||||||
|
<p>Butte, MT 59701</p>
|
||||||
|
</a>
|
||||||
|
<p><a href="tel:+1-406-494-5028" class="phone">(406) 494 - 5028</a></p>
|
||||||
|
<p>Pastor Ron Derksen</p>
|
||||||
|
<p>Associate Pastor Derek Loewen</p>
|
||||||
|
</div>
|
||||||
|
<div id="footer-services-content" class="footer-panel">
|
||||||
|
<p>Sunday School: 10AM</p>
|
||||||
|
<p>Sunday Worship: 11AM</p>
|
||||||
|
<p>Sunday Evening: 7PM</p>
|
||||||
|
<p>Wednesday Evening: 7PM</p>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
<div id="footer-website-content" class="footer-panel">
|
||||||
|
<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>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="audio-player-filler" [hidden]="!showAudioPlayer" ></div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<div class="audio-player" [class.audio-player-slide-up]="showAudioPlayer">
|
||||||
|
<audio-player-component (closed)="audioPlayerClosed()" (started)="audioPlayerStarted()"></audio-player-component>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<menu-component [menuOpen]="menuOpen" (closed)="mainMenuClick()"></menu-component>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
import { GoogleAnalyticsService } from './../../services/google-analytics.service';
|
||||||
|
import { MatDialog, MatDialogConfig, MatSnackBar } from '@angular/material';
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { EventService } from './../../services/event.service';
|
||||||
|
import { AudioPlayerService } from './../../services/audio-player.service';
|
||||||
|
import { AddEventPopupComponent } from './../popups/add-event-popup/add-event-popup.component';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
import { Event } from '../../interfaces/event';
|
||||||
|
|
||||||
|
import { LoginService } from '../../services/login.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-events-page',
|
||||||
|
templateUrl: './events-page.component.html',
|
||||||
|
styleUrls: ['./events-page.component.css']
|
||||||
|
})
|
||||||
|
export class EventsPageComponent implements OnInit {
|
||||||
|
|
||||||
|
private dialogConfig: MatDialogConfig;
|
||||||
|
public loading: boolean = true;
|
||||||
|
public events: Event[];
|
||||||
|
public loggedIn: boolean = false;
|
||||||
|
public showAllButtonVisible: boolean = false;
|
||||||
|
public audioPlayerOpen: boolean = false;
|
||||||
|
|
||||||
|
constructor(private loginService: LoginService,
|
||||||
|
private eventService: EventService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
private snackbar: MatSnackBar,
|
||||||
|
private activatedRoute: ActivatedRoute,
|
||||||
|
private audioPlayerService: AudioPlayerService,
|
||||||
|
private googleAnalyticsService: GoogleAnalyticsService) {
|
||||||
|
this.loginService.isLoggedIn(true).subscribe(is => { this.loggedIn = is; });
|
||||||
|
this.loginService.onLogin().subscribe(is => { this.loggedIn = is.isLoggedIn; });
|
||||||
|
this.audioPlayerService.onAudioPlayerOpenClose.subscribe(is => this.audioPlayerOpen = is);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.activatedRoute.params
|
||||||
|
.subscribe((params: Params) =>{
|
||||||
|
let id = +params['id'];
|
||||||
|
id = Number.isNaN(id) ? -1 : id;
|
||||||
|
if (id > -1){
|
||||||
|
this.getSingleEvent(id);
|
||||||
|
this.showAllButtonVisible = true;
|
||||||
|
} else {
|
||||||
|
this.getEvents(true);
|
||||||
|
this.showAllButtonVisible = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getEvents(clearExisting: boolean): void{
|
||||||
|
this.loading = true;
|
||||||
|
this.events = this.events || [];
|
||||||
|
if (clearExisting){
|
||||||
|
this.events = [];
|
||||||
|
}
|
||||||
|
this.eventService.getEvents(1).subscribe(
|
||||||
|
eventReponse => {
|
||||||
|
this.addEvents(eventReponse.events);
|
||||||
|
this.loading = false;
|
||||||
|
},
|
||||||
|
error => console.error(error)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSingleEvent(id: Number): void{
|
||||||
|
this.events = [];
|
||||||
|
this.loading = true;
|
||||||
|
this.eventService.getSingleEvent(id).subscribe(event => {
|
||||||
|
this.events.push(event.event);
|
||||||
|
this.loading = false;
|
||||||
|
this.googleAnalyticsService.shareEventConversion(event.event.id,event.event.title);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addEvents(events: Event[]): void{
|
||||||
|
console.log(events);
|
||||||
|
for(let i = 0; i < events.length; i++){
|
||||||
|
this.events.push(events[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addEvent(){
|
||||||
|
let dialog = this.dialog.open(AddEventPopupComponent,this.dialogConfig);
|
||||||
|
|
||||||
|
dialog.afterClosed().subscribe(e => {
|
||||||
|
e = e as Event;
|
||||||
|
if (e != null){
|
||||||
|
this.events.unshift(e);
|
||||||
|
let snack = this.snackbar.open(e.title + " was added!", "Ok");
|
||||||
|
snack.onAction().subscribe(() => {
|
||||||
|
snack.dismiss();
|
||||||
|
});
|
||||||
|
setTimeout(() => { snack.dismiss(); },3000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
#content-wrapper{
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
a{
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited{
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
img{
|
||||||
|
width: 70%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.full {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action{
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 20px;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-block{
|
||||||
|
display: inline-block;
|
||||||
|
width: calc(60% - 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.row{
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-top: 10px;
|
||||||
|
background-color: white;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-background{
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1000;
|
||||||
|
left: 0;
|
||||||
|
top: -10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-content{
|
||||||
|
width: 1000px;
|
||||||
|
margin: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden; /*Keep floating children inside this element */
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-content-single-col{
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
padding-top: 40px;
|
||||||
|
padding-bottom: 40px;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-content-col-left, .row-content-col-right{
|
||||||
|
display: inline-block;
|
||||||
|
width: calc(50% - 5px);
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-content-col-right{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-content-header{
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-top{
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
#background-image{
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
z-index: -1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(min-width:400px){
|
||||||
|
#background-image{
|
||||||
|
top: -15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media(min-width:500px){
|
||||||
|
#background-image{
|
||||||
|
top: -30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media(min-width:700px){
|
||||||
|
#background-image{
|
||||||
|
top: -45px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media(min-width:900px){
|
||||||
|
#background-image{
|
||||||
|
top: -60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media(min-width:1100px){
|
||||||
|
#background-image{
|
||||||
|
top: -75px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media(min-width:1300px){
|
||||||
|
#background-image{
|
||||||
|
top: -100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#filler{
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 35%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.tint{
|
||||||
|
background-color: rgb(240,240,240);
|
||||||
|
border-top: 1px solid rgb(200,200,200);
|
||||||
|
border-bottom: 1px solid rgb(220,220,220);
|
||||||
|
}
|
||||||
|
|
||||||
|
.see-through{
|
||||||
|
background-color: rgba(0,0,0,.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.see-through-light{
|
||||||
|
background-color: rgba(0,0,0,.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.verse{
|
||||||
|
font-style: italic;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@media(max-width: 850px){
|
||||||
|
.row-content-col-left, .row-content-col-right{
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
float:none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
img.full {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
|
||||||
|
<img id="background-image" src="assets/images/home-images/tiny/sunset_b.jpg" alt="background image" width="100%">
|
||||||
|
|
||||||
|
<div id="filler">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content-wrapper">
|
||||||
|
|
||||||
|
<div class="row tint" *ngIf="showSpecial" >
|
||||||
|
<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>
|
||||||
|
<div class="row-content-col-right align-top center">
|
||||||
|
<p ofbFadeInOnScroll class="row-content-header">Champ the Smiling Trick Horse</p>
|
||||||
|
<p ofbFadeInOnScroll>
|
||||||
|
Come join us for this special event happening September 5th and 6th at Old Fashion Baptist!
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
<p ofbFadeInOnScroll>
|
||||||
|
<b>Wednesday, September 5 @ 7 PM</b>
|
||||||
|
<br>
|
||||||
|
Bible Preaching & Bluegrass Gospel Music
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
<p ofbFadeInOnScroll>
|
||||||
|
<b>Thursday, September 6 @ 5:30 PM</b>
|
||||||
|
<br>
|
||||||
|
Food, Games, Music & Preaching
|
||||||
|
</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>
|
||||||
|
<br>
|
||||||
|
<p ofbFadeInOnScroll class="action">
|
||||||
|
<i ofbicon>phone</i> <a href="tel:+1-406-494-5028" class="align-top">406-494-5028</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="row-content">
|
||||||
|
<div class="row-content-col-left 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
|
||||||
|
Baptist and we look forward to seeing you!</p>
|
||||||
|
<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">
|
||||||
|
<!-- <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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row tint">
|
||||||
|
<div class="row-content">
|
||||||
|
<div class="row-content-single-col">
|
||||||
|
<p ofbFadeInOnScroll ofbGrowWhenCenter class="verse">O give thanks unto the Lord; for he is good: because his mercy endureth for ever. - Psalm 118:1</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="row-content">
|
||||||
|
<div class="row-content-col-right align-top">
|
||||||
|
<p ofbFadeInOnScroll class="row-content-header">Need a ride?</p>
|
||||||
|
<p ofbFadeInOnScroll>
|
||||||
|
Want to come but don't have a way to get here? We would be happy
|
||||||
|
to pick you up! Give us a call to schedule a ride on Sunday Morning.
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
<p ofbFadeInOnScroll class="action">
|
||||||
|
<i ofbicon>phone</i> <a href="tel:+1-406-494-5028" class="align-top">406-494-5028</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="row-content-col-left">
|
||||||
|
<a href="tel:+1-406-494-5028"><img ofbFadeInOnScroll src="assets/images/home-images/tiny/bus2.jpg" height="200"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row tint">
|
||||||
|
<div class="row-content">
|
||||||
|
<div class="row-content-single-col">
|
||||||
|
<p ofbFadeInOnScroll class="verse">The fear of the LORD is the beginning of wisdom: and the knowledge of the holy is understanding. - Proverbs 9:10</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="row-content">
|
||||||
|
<div class="row-content-col-left align-top">
|
||||||
|
<p ofbFadeInOnScroll class="row-content-header">The Holy Bible</p>
|
||||||
|
<div ofbFadeInOnScroll>
|
||||||
|
Here at Old Fashion Baptist Church we love the Word of God!
|
||||||
|
<p class="verse">
|
||||||
|
But he answered and said, <span class="red">It is written, Man shall not live by bread alone, but by every word that proceedeth out of the mouth of God.</span> - Matthew 4:4</p>
|
||||||
|
We encourage you to come and join as as we study, teach and preach Gods Word!
|
||||||
|
<br><br>
|
||||||
|
<p class="action">
|
||||||
|
<i ofbicon>directions</i> <a target="_blank" class="align-top" 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">Get Directions</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row-content-col-right">
|
||||||
|
<a target="_blank" class="align-top" 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"><img ofbFadeInOnScroll src="assets/images/home-images/tiny/bible.jpg"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row tint">
|
||||||
|
<div class="row-content">
|
||||||
|
<div class="row-content-single-col">
|
||||||
|
<p ofbFadeInOnScroll class="verse">Not forsaking the assembling of ourselves together, as the manner of some is; but exhorting one another: and so much the more, as ye see the day approaching. - Hebrews 10:25</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="row-content">
|
||||||
|
<div class="row-content-col-right align-top">
|
||||||
|
<p ofbFadeInOnScroll class="row-content-header">Listen Online</p>
|
||||||
|
<p ofbFadeInOnScroll>
|
||||||
|
Many of our sermons are posted online. It is our prayer that these would be helpful and would encourage you in your walk with the Lord.
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
<p ofbFadeInOnScroll class="action">
|
||||||
|
<i ofbicon>headset</i> <a routerLink="/sermons" class="align-top">Click here to listen online</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="row-content-col-left">
|
||||||
|
<a routerLink="/sermons"><img ofbFadeInOnScroll src="assets/images/home-images/tiny/headphones.png" height="200"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Component, HostListener } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'home-component',
|
||||||
|
templateUrl: './home.component.html',
|
||||||
|
styleUrls: ['./home.component.css'],
|
||||||
|
})
|
||||||
|
export class HomeComponent {
|
||||||
|
backgroundTop: string = "0px";
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener('window:scroll', ['$event'])
|
||||||
|
onScroll(event){
|
||||||
|
let scrollTop = event.target.documentElement.scrollTop || event.target.body.scrollTop || window.pageYOffset;
|
||||||
|
//this.backgroundTop = Math.min((scrollTop * .30),100) * -1 + "px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
import { EventService } from './../../../services/event.service';
|
||||||
|
import { OkPopupComponent } from './../ok-popup/ok-popup.component';
|
||||||
|
import { LoginPopupComponent } from './../login-popup/login-popup.component';
|
||||||
|
import { MatDialog, MatDialogRef, MatSnackBar } from '@angular/material';
|
||||||
|
import { Event } from './../../../interfaces/event';
|
||||||
|
import { LoginService } from './../../../services/login.service';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-add-event-popup',
|
||||||
|
templateUrl: './add-event-popup.component.html',
|
||||||
|
styleUrls: ['./add-event-popup.component.css']
|
||||||
|
})
|
||||||
|
export class AddEventPopupComponent implements OnInit {
|
||||||
|
public addEventButtonText: string = "Add Event";
|
||||||
|
public addEventButtonDisabled: boolean = false;
|
||||||
|
|
||||||
|
public eventTitle: string;
|
||||||
|
public eventStartDate: Date = new Date();
|
||||||
|
private _eventEndDate: Date = new Date();
|
||||||
|
public get eventEndDate(): Date{
|
||||||
|
if (new Date(this.eventStartDate).getTime() > new Date(this._eventEndDate).getTime()){
|
||||||
|
this._eventEndDate = this.eventStartDate;
|
||||||
|
}
|
||||||
|
return this._eventEndDate;
|
||||||
|
}
|
||||||
|
public set eventEndDate(val: Date){
|
||||||
|
this._eventEndDate = val;
|
||||||
|
}
|
||||||
|
public eventDescription: string;
|
||||||
|
|
||||||
|
|
||||||
|
public errorMessages: string[] = [];
|
||||||
|
|
||||||
|
constructor(private MatDialog: MatDialog, private MatDialogRef: MatDialogRef<AddEventPopupComponent>, private loginService: LoginService, private eventService: EventService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(){
|
||||||
|
this.updateAddButton(false);
|
||||||
|
|
||||||
|
//First check to see if we are logged in
|
||||||
|
this.loginService.isLoggedIn(true).subscribe(is => {
|
||||||
|
if (is === true){
|
||||||
|
this.addEvent();
|
||||||
|
} else {
|
||||||
|
let popup = this.MatDialog.open(LoginPopupComponent);
|
||||||
|
popup.afterClosed().subscribe(r => {
|
||||||
|
if (r === true){
|
||||||
|
this.addEvent();
|
||||||
|
} else {
|
||||||
|
this.updateAddButton(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error =>{
|
||||||
|
this.updateAddButton(true);
|
||||||
|
let errorDialog = this.MatDialog.open(OkPopupComponent,{data:{title:'Error',message:'There was an error adding the event\n' + error}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAddButton(enable: boolean){
|
||||||
|
if (enable){
|
||||||
|
this.addEventButtonText = "Add Event";
|
||||||
|
} else {
|
||||||
|
this.addEventButtonText = "Please Wait...";
|
||||||
|
}
|
||||||
|
this.addEventButtonDisabled = !enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private addEvent(): void {
|
||||||
|
//Check fields
|
||||||
|
this.errorMessages = [];
|
||||||
|
if (this.eventTitle == null || this.eventTitle == ""){
|
||||||
|
this.errorMessages.push("Please enter a title");
|
||||||
|
}
|
||||||
|
if (this.eventStartDate == null){
|
||||||
|
this.errorMessages.push("Please enter a event start date");
|
||||||
|
}
|
||||||
|
if (this.eventEndDate == null){
|
||||||
|
this.errorMessages.push("Please enter a event end date");
|
||||||
|
}
|
||||||
|
if (this.eventDescription == null || this.eventDescription == ""){
|
||||||
|
this.errorMessages.push("Please enter a description");
|
||||||
|
}
|
||||||
|
if (this.errorMessages.length > 0){ this.updateAddButton(true); return; }
|
||||||
|
|
||||||
|
let e = new Event();
|
||||||
|
e.title = this.eventTitle;
|
||||||
|
e.startDate = this.eventStartDate;
|
||||||
|
e.endDate = this.eventEndDate;
|
||||||
|
e.description = this.eventDescription;
|
||||||
|
|
||||||
|
this.eventService.addEvent(e).subscribe(
|
||||||
|
data=>{
|
||||||
|
this.updateAddButton(true);
|
||||||
|
this.MatDialogRef.close(data['event']);
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.updateAddButton(true);
|
||||||
|
let errorDialog = this.MatDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel(evt){
|
||||||
|
evt.preventDefault();
|
||||||
|
this.MatDialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
import { OkPopupComponent } from './../ok-popup/ok-popup.component';
|
||||||
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
import { LoginPopupComponent } from './../login-popup/login-popup.component';
|
||||||
|
import { MatDialog, MatDialogRef, MatSnackBar } from '@angular/material';
|
||||||
|
import { Sermon } from './../../../interfaces/sermon';
|
||||||
|
import { SermonService } from './../../../services/sermon.service';
|
||||||
|
import { LoginService } from './../../../services/login.service';
|
||||||
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
|
import { HttpEvent, HttpEventType } from '@angular/common/http';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-add-sermon-popup',
|
||||||
|
templateUrl: './add-sermon-popup.component.html',
|
||||||
|
styleUrls: ['./add-sermon-popup.component.css']
|
||||||
|
})
|
||||||
|
export class AddSermonPopupComponent implements OnInit {
|
||||||
|
public addSermonButtonText: string = "Add Sermon";
|
||||||
|
public addSermonButtonDisabled: boolean = false;
|
||||||
|
|
||||||
|
public sermonTitle: string;
|
||||||
|
public sermonDate: Date = new Date();
|
||||||
|
public sermonSpeaker: string;
|
||||||
|
public sermonDescription: string;
|
||||||
|
public sermonFile: File;
|
||||||
|
|
||||||
|
public errorMessages: string[] = [];
|
||||||
|
|
||||||
|
public uploadTotal: number = 100;
|
||||||
|
public uploadProgress: number = 0;
|
||||||
|
public monitorProgress: boolean;
|
||||||
|
|
||||||
|
private progressSubscription: Subscription;
|
||||||
|
|
||||||
|
constructor(private MatDialog: MatDialog, private MatDialogRef: MatDialogRef<AddSermonPopupComponent>, private loginService: LoginService, private sermonService: SermonService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(){
|
||||||
|
this.updateAddButton(false);
|
||||||
|
|
||||||
|
//First check to see if we are logged in
|
||||||
|
this.loginService.isLoggedIn(true).subscribe(is => {
|
||||||
|
if (is === true){
|
||||||
|
this.addSermon();
|
||||||
|
} else {
|
||||||
|
let popup = this.MatDialog.open(LoginPopupComponent);
|
||||||
|
popup.afterClosed().subscribe(r => {
|
||||||
|
if (r === true){
|
||||||
|
this.addSermon();
|
||||||
|
} else {
|
||||||
|
this.updateAddButton(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error =>{
|
||||||
|
this.updateAddButton(true);
|
||||||
|
let errorDialog = this.MatDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAddButton(enable: boolean){
|
||||||
|
if (enable){
|
||||||
|
this.addSermonButtonText = "Add Sermon";
|
||||||
|
} else {
|
||||||
|
this.addSermonButtonText = "Please Wait...";
|
||||||
|
}
|
||||||
|
this.addSermonButtonDisabled = !enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private addSermon(): void {
|
||||||
|
//Check fields
|
||||||
|
this.errorMessages = [];
|
||||||
|
if (this.sermonTitle == null || this.sermonTitle == ""){
|
||||||
|
this.errorMessages.push("Please enter a title");
|
||||||
|
}
|
||||||
|
if (this.sermonDate == null){
|
||||||
|
this.errorMessages.push("Please enter a sermon date");
|
||||||
|
}
|
||||||
|
if (this.sermonSpeaker == null || this.sermonSpeaker == ""){
|
||||||
|
this.errorMessages.push("Please enter a speaker");
|
||||||
|
}
|
||||||
|
if (this.sermonDescription == null || this.sermonDescription == ""){
|
||||||
|
this.errorMessages.push("Please enter a description");
|
||||||
|
}
|
||||||
|
if (this.sermonFile == null){
|
||||||
|
this.errorMessages.push("Please add a sermon MP3 file");
|
||||||
|
}
|
||||||
|
if (this.sermonFile != null && this.sermonFile.type != 'audio/mp3'){
|
||||||
|
this.errorMessages.push("File must be a MP3");
|
||||||
|
}
|
||||||
|
if (this.errorMessages.length > 0){ this.updateAddButton(true); return; }
|
||||||
|
|
||||||
|
let s = new Sermon();
|
||||||
|
s.title = this.sermonTitle;
|
||||||
|
s.author = this.sermonSpeaker;
|
||||||
|
s.description = this.sermonDescription;
|
||||||
|
s.date = this.sermonDate;
|
||||||
|
|
||||||
|
//Start monitoring Progress
|
||||||
|
this.monitorProgress = true;
|
||||||
|
|
||||||
|
this.sermonService.addSermon(s,this.sermonFile).subscribe(
|
||||||
|
data => {this.getEventMessage(data); },
|
||||||
|
error => {
|
||||||
|
alert(error);
|
||||||
|
this.updateAddButton(true);
|
||||||
|
this.monitorProgress = false;
|
||||||
|
let errorDialog = this.MatDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getEventMessage(event: HttpEvent<any>) {
|
||||||
|
switch (event.type) {
|
||||||
|
case HttpEventType.Sent:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case HttpEventType.UploadProgress:
|
||||||
|
this.uploadProgress = event.loaded;
|
||||||
|
this.uploadTotal = event.total;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case HttpEventType.Response:
|
||||||
|
this.updateAddButton(true);
|
||||||
|
this.monitorProgress = false;
|
||||||
|
this.MatDialogRef.close(event['body']['sermon']);
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onFileChange(event){
|
||||||
|
this.sermonFile = event.srcElement.files[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel(evt){
|
||||||
|
evt.preventDefault();
|
||||||
|
this.MatDialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { OkPopupComponent } from './../ok-popup/ok-popup.component';
|
||||||
|
import { MatSnackBar, MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material';
|
||||||
|
import { LoginService } from './../../../services/login.service';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login-popup',
|
||||||
|
templateUrl: './login-popup.component.html',
|
||||||
|
styleUrls: ['./login-popup.component.css']
|
||||||
|
})
|
||||||
|
export class LoginPopupComponent implements OnInit {
|
||||||
|
public loginButtonText: string = 'Login';
|
||||||
|
public loginButtonDisabled: boolean = false;
|
||||||
|
public username: string;
|
||||||
|
public password: string;
|
||||||
|
|
||||||
|
constructor(private MatDialog: MatDialog, private MatDialogRef: MatDialogRef<LoginPopupComponent>, private loginService: LoginService, private snackbar: MatSnackBar) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(){
|
||||||
|
this.loginButtonText = 'Please Wait...';
|
||||||
|
this.loginButtonDisabled = true;
|
||||||
|
this.loginService.login(this.username,this.password).subscribe(
|
||||||
|
(data:any) => {
|
||||||
|
if (data.message === 'Logged In'){
|
||||||
|
this.MatDialogRef.close(true);
|
||||||
|
let s = this.snackbar.open("Logged In","OK");
|
||||||
|
s.onAction().subscribe(()=>{ s.dismiss(); });
|
||||||
|
s.afterOpened().subscribe(()=>{ setTimeout(()=>{ s.dismiss(); },3000); });
|
||||||
|
} else {
|
||||||
|
this.showLoginError(data.message);
|
||||||
|
}
|
||||||
|
this.loginButtonText = 'Login';
|
||||||
|
this.loginButtonDisabled = false;
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
console.error(error);
|
||||||
|
this.showLoginError(error);
|
||||||
|
this.loginButtonText = 'Login';
|
||||||
|
this.loginButtonDisabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
showLoginError(message: string){
|
||||||
|
let opts = new MatDialogConfig;
|
||||||
|
opts.data = { title:'Login Error','message':message };
|
||||||
|
let popup = this.MatDialog.open(OkPopupComponent,opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel(){
|
||||||
|
this.MatDialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
import { LoginPopupComponent } from './../login-popup/login-popup.component';
|
||||||
|
import { OkPopupComponent } from './../ok-popup/ok-popup.component';
|
||||||
|
import { Sermon } from './../../../interfaces/sermon';
|
||||||
|
import { SermonService } from './../../../services/sermon.service';
|
||||||
|
import { LoginService } from './../../../services/login.service';
|
||||||
|
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||||
|
import { Component, OnInit, Inject } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-update-sermon-popup',
|
||||||
|
templateUrl: './update-sermon-popup.component.html',
|
||||||
|
styleUrls: ['./update-sermon-popup.component.css']
|
||||||
|
})
|
||||||
|
export class UpdateSermonPopupComponent implements OnInit {
|
||||||
|
public updateSermonButtonText: string = "Update Sermon";
|
||||||
|
public updateSermonButtonDisabled: boolean = false;
|
||||||
|
|
||||||
|
public sermonId: number;
|
||||||
|
public sermonTitle: string;
|
||||||
|
public sermonDate: Date = new Date();
|
||||||
|
public sermonSpeaker: string;
|
||||||
|
public sermonDescription: string;
|
||||||
|
|
||||||
|
constructor(@Inject(MAT_DIALOG_DATA) private data: any,
|
||||||
|
private MatDialog: MatDialog,
|
||||||
|
private MatDialogRef: MatDialogRef<UpdateSermonPopupComponent>,
|
||||||
|
private loginService: LoginService,
|
||||||
|
private sermonService: SermonService) {
|
||||||
|
|
||||||
|
this.sermonId = this.data.id;
|
||||||
|
this.sermonTitle = this.data.title;
|
||||||
|
this.sermonDate = this.data.date;
|
||||||
|
this.sermonSpeaker = this.data.author;
|
||||||
|
this.sermonDescription = this.data.description;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(){
|
||||||
|
this.updateButton(false);
|
||||||
|
|
||||||
|
//First check to see if we are logged in
|
||||||
|
this.loginService.isLoggedIn(true).subscribe(is => {
|
||||||
|
if (is === true){
|
||||||
|
this.updateSermon();
|
||||||
|
} else {
|
||||||
|
let popup = this.MatDialog.open(LoginPopupComponent);
|
||||||
|
popup.afterClosed().subscribe(r => {
|
||||||
|
if (r === true){
|
||||||
|
this.updateSermon();
|
||||||
|
} else {
|
||||||
|
this.updateButton(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error =>{
|
||||||
|
this.updateButton(true);
|
||||||
|
let errorDialog = this.MatDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateSermon(): void {
|
||||||
|
let s = new Sermon;
|
||||||
|
s.id = this.sermonId;
|
||||||
|
s.title = this.sermonTitle;
|
||||||
|
s.author = this.sermonSpeaker;
|
||||||
|
s.description = this.sermonDescription;
|
||||||
|
s.date = this.sermonDate;
|
||||||
|
|
||||||
|
//Start monitoring Progress
|
||||||
|
this.sermonService.updateSermon(s).subscribe(
|
||||||
|
(data:any)=>{
|
||||||
|
this.MatDialogRef.close(data.sermon);
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.updateButton(true);
|
||||||
|
let errorDialog = this.MatDialog.open(OkPopupComponent,{data:{title:'Update Error',message:'There was an error updating the sermon\n' + error}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateButton(enable: boolean){
|
||||||
|
if (enable){
|
||||||
|
this.updateSermonButtonText = "Update Sermon";
|
||||||
|
} else {
|
||||||
|
this.updateSermonButtonText = "Please Wait...";
|
||||||
|
}
|
||||||
|
this.updateSermonButtonDisabled = !enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel(){
|
||||||
|
this.MatDialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="sermon-container">
|
||||||
|
<p class="sermon-header" >Recent Sermons</p>
|
||||||
|
<p *ngIf="loading">Loading...</p>
|
||||||
|
<ul class="sermons">
|
||||||
|
<li *ngFor="let sermon of sermons; let i = index;">
|
||||||
|
<sermon-small-component
|
||||||
|
[title]="sermon.title"
|
||||||
|
[date]="sermon.date"
|
||||||
|
[delayFadeIn]="(i+1)*200"
|
||||||
|
[url]="sermon.file"
|
||||||
|
[id]="sermon.id"
|
||||||
|
></sermon-small-component>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Sermon } from '../../interfaces/sermon';
|
||||||
|
import { SermonService } from '../../services/sermon.service';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'recent-sermons-component',
|
||||||
|
templateUrl: './recent-sermons.component.html',
|
||||||
|
styleUrls: ['./recent-sermons.component.css']
|
||||||
|
})
|
||||||
|
export class RecentSermonsComponent implements OnInit {
|
||||||
|
sermons: Sermon[];
|
||||||
|
loading: boolean = false;
|
||||||
|
@Input()
|
||||||
|
numberOfSermonsToShow = 3;
|
||||||
|
|
||||||
|
constructor(private sermonService: SermonService){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.getSermons();
|
||||||
|
}
|
||||||
|
|
||||||
|
getSermons(): void{
|
||||||
|
this.sermons = [];
|
||||||
|
this.loading = true;
|
||||||
|
this.sermonService.getSermons(this.numberOfSermonsToShow).subscribe(response => {
|
||||||
|
this.sermons = response.sermons;
|
||||||
|
this.loading = false;
|
||||||
|
console.log(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { Component, AfterContentInit, Input } from '@angular/core';
|
||||||
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||||
|
import { AudioPlayerService } from '../../services/audio-player.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'sermon-small-component',
|
||||||
|
templateUrl: './sermon-small.component.html',
|
||||||
|
styleUrls: ['./sermon-small.component.css'],
|
||||||
|
animations:[
|
||||||
|
trigger("inout",[
|
||||||
|
state("1", style({ opacity: '1', transform:'translateX(0)' })),
|
||||||
|
state("0",style({ opacity: '0', transform:'translateX(5%)' })),
|
||||||
|
transition('* => 1',[
|
||||||
|
animate('500ms ease-in-out')
|
||||||
|
]),
|
||||||
|
transition(':enter',[
|
||||||
|
animate('0ms')
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class SermonSmallComponent implements AfterContentInit {
|
||||||
|
@Input()
|
||||||
|
id: number;
|
||||||
|
@Input()
|
||||||
|
title: string;
|
||||||
|
@Input()
|
||||||
|
description: string;
|
||||||
|
@Input()
|
||||||
|
date: Date;
|
||||||
|
@Input()
|
||||||
|
author: string;
|
||||||
|
@Input()
|
||||||
|
url: string;
|
||||||
|
public startFadeIn: boolean = false;
|
||||||
|
@Input()
|
||||||
|
public delayFadeIn: number = 100;
|
||||||
|
|
||||||
|
constructor(private audioPlayer: AudioPlayerService){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
play(): void{
|
||||||
|
|
||||||
|
if (this.audioPlayer.getIsPlaying() == true && this.audioPlayer.getMetaData() != null && this.audioPlayer.getMetaData().id == this.id){
|
||||||
|
this.audioPlayer.pause();
|
||||||
|
} else {
|
||||||
|
if (this.audioPlayer.getMetaData() != null && this.audioPlayer.getMetaData().id == this.id){
|
||||||
|
this.audioPlayer.resume();
|
||||||
|
} else {
|
||||||
|
this.audioPlayer.play(this.url,{id:this.id,title:this.title,author:this.author});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterContentInit(): void{
|
||||||
|
setTimeout(() => this.startFadeIn = true, this.delayFadeIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||||
|
<div mainContent>
|
||||||
|
<div class="mobile-search">
|
||||||
|
<mat-form-field class="width100">
|
||||||
|
<input #searchMobile matInput placeholder="Search Sermons" [value]="searchTerm" (keyup)="searchChange(searchMobile.value)">
|
||||||
|
</mat-form-field>
|
||||||
|
<br><br>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let sermon of sermons; let i = index;">
|
||||||
|
<sermon-large-component
|
||||||
|
[id]="sermon.id"
|
||||||
|
[title]="sermon.title"
|
||||||
|
[date]="sermon.date"
|
||||||
|
[description]="sermon.description"
|
||||||
|
[author]="sermon.author"
|
||||||
|
[delayFadeIn]="(i-((((sermons.length*10)/10)-10) > 0 ? (((sermons.length*10)/10)-10) : 0))*200"
|
||||||
|
[url]="sermon.file"
|
||||||
|
[loggedIn]="loggedIn"
|
||||||
|
></sermon-large-component>
|
||||||
|
</li>
|
||||||
|
<button mat-button [disabled]="loading" class="width100" style="text-align: center;" (click)="loadMoreSermonsClick()">
|
||||||
|
<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>
|
||||||
|
</ul>
|
||||||
|
<div class="fab-buttons" >
|
||||||
|
<button mat-fab (click)="searchFabClick()"><i ofbicon>search</i></button>
|
||||||
|
<button mat-fab *ngIf="loggedIn" (click)="addSermon()"><i ofbicon>add</i></button>
|
||||||
|
<div id="audio-player-filler" *ngIf="audioPlayerOpen"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div sideBar class="side-bar">
|
||||||
|
<div class="search-bar">
|
||||||
|
<mat-form-field class="width100">
|
||||||
|
<input #search matInput placeholder="Search Sermons" [value]="searchTerm" (keyup)="searchChange(search.value)">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<button mat-raised-button *ngIf="loggedIn" class="width100" (click)="addSermon()" >Add Sermon</button>
|
||||||
|
</div>
|
||||||
|
</secondary-page-component>
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
import { InputPopupComponent } from './../popups/input-popup/input-popup.component';
|
||||||
|
import { AudioPlayerService } from './../../services/audio-player.service';
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { SermonService } from '../../services/sermon.service';
|
||||||
|
import { LoginService } from '../../services/login.service';
|
||||||
|
import { Sermon } from '../../interfaces/sermon';
|
||||||
|
import { MatSnackBar, MatDialog, MatDialogConfig } from '@angular/material';
|
||||||
|
|
||||||
|
import { AddSermonPopupComponent } from '../popups/add-sermon-popup/add-sermon-popup.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'sermons-component',
|
||||||
|
templateUrl: './sermons.component.html',
|
||||||
|
styleUrls: ['./sermons.component.css'],
|
||||||
|
})
|
||||||
|
export class SermonsComponent implements OnInit {
|
||||||
|
|
||||||
|
|
||||||
|
public sermons: Sermon[];
|
||||||
|
public loading: boolean = false;
|
||||||
|
public page: number = 1;
|
||||||
|
public searchTerm: string = '';
|
||||||
|
public loggedIn: boolean = false;
|
||||||
|
public audioPlayerOpen: boolean;
|
||||||
|
private searchWait: any;
|
||||||
|
private dialogConfig: MatDialogConfig;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private loginService: LoginService,
|
||||||
|
private snackbar: MatSnackBar,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
private sermonService: SermonService,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private location: Location,
|
||||||
|
private audioPlayerService: AudioPlayerService){
|
||||||
|
|
||||||
|
this.loginService.isLoggedIn(true).subscribe(is => { this.loggedIn = is; });
|
||||||
|
this.loginService.onLogin().subscribe(is => { this.loggedIn = is.isLoggedIn; });
|
||||||
|
this.audioPlayerService.onAudioPlayerOpenClose.subscribe(is => { this.audioPlayerOpen = is; });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ngOnInit(): void{
|
||||||
|
this.route.params
|
||||||
|
// (+) converts string 'id' to a number
|
||||||
|
.subscribe((params: Params) => {
|
||||||
|
let id = +params['id'];
|
||||||
|
id = Number.isNaN(id) ? -1 : id;
|
||||||
|
if (id > -1){
|
||||||
|
this.page = 0;
|
||||||
|
this.getSingleSermon(id);
|
||||||
|
} else {
|
||||||
|
this.getSermons(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
searchChange(searchTerm): void{
|
||||||
|
this.searchTerm = searchTerm;
|
||||||
|
if (this.searchWait) clearTimeout(this.searchWait);
|
||||||
|
this.searchWait = setTimeout(()=>this.getSermons(true),400);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMoreSermonsClick(): void{
|
||||||
|
this.page++;
|
||||||
|
//this.location.go("/sermons/" + this.page);
|
||||||
|
this.getSermons(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSingleSermon(id: number){
|
||||||
|
this.loading = true;
|
||||||
|
this.sermons = this.sermons || [];
|
||||||
|
this.sermons = [];
|
||||||
|
|
||||||
|
this.sermonService.getSermonById(id).subscribe(
|
||||||
|
response => {
|
||||||
|
this.sermons.push(response.sermon)
|
||||||
|
this.loading = false;
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.getSermons(true);
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
getSermons(clearExisting): void{
|
||||||
|
this.loading = true;
|
||||||
|
this.sermons = this.sermons || [];
|
||||||
|
if (clearExisting) {
|
||||||
|
this.sermons = [];
|
||||||
|
this.page = 1;
|
||||||
|
}
|
||||||
|
this.sermonService.searchSermons(this.searchTerm,this.page).subscribe(
|
||||||
|
response => {
|
||||||
|
this.addSermons(response.sermons);
|
||||||
|
this.loading = false;
|
||||||
|
},
|
||||||
|
error => console.error(error) );
|
||||||
|
}
|
||||||
|
|
||||||
|
addSermons(sermons: Sermon[]): void{
|
||||||
|
for(let i = 0; i < sermons.length; i++){
|
||||||
|
this.sermons.push(sermons[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addSermon(){
|
||||||
|
let dialog = this.dialog.open(AddSermonPopupComponent,this.dialogConfig);
|
||||||
|
|
||||||
|
dialog.afterClosed().subscribe(s => {
|
||||||
|
s = s as Sermon;
|
||||||
|
if (s){
|
||||||
|
this.sermons.unshift(s);
|
||||||
|
let snack = this.snackbar.open(s.title + " was added!", "Ok");
|
||||||
|
snack.onAction().subscribe(()=>{
|
||||||
|
snack.dismiss();
|
||||||
|
});
|
||||||
|
setTimeout(()=>{snack.dismiss();},3000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
searchFabClick(){
|
||||||
|
let opts = new MatDialogConfig;
|
||||||
|
opts.data = { title:'Search','message':'' };
|
||||||
|
|
||||||
|
let dialog = this.dialog.open(InputPopupComponent,opts);
|
||||||
|
|
||||||
|
dialog.afterClosed().subscribe(search => {
|
||||||
|
if (typeof search !== 'undefined' && this.searchTerm != search){
|
||||||
|
this.searchTerm = search;
|
||||||
|
this.searchChange(this.searchTerm);
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Event } from '../../interfaces/event';
|
||||||
|
import { EventService } from '../../services/event.service';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'upcoming-events-component',
|
||||||
|
templateUrl: './upcoming-events.component.html',
|
||||||
|
styleUrls: ['./upcoming-events.component.css']
|
||||||
|
})
|
||||||
|
export class UpcomingEventsComponent implements OnInit {
|
||||||
|
public events: Event[];
|
||||||
|
loading: boolean = false;
|
||||||
|
@Input()
|
||||||
|
numberOfEventsToShow: number = 3;
|
||||||
|
@Input()
|
||||||
|
hideWhenNoEvents: boolean = true;
|
||||||
|
|
||||||
|
constructor(private eventService: EventService){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.getEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
getEvents(): void{
|
||||||
|
this.events = [];
|
||||||
|
this.loading = true;
|
||||||
|
this.eventService.getEvents(1).subscribe(events => {
|
||||||
|
this.events = events.events.slice(0,this.numberOfEventsToShow);
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { environment } from '../../environments/environment';
|
||||||
|
|
||||||
|
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 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_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 LOGIN_URL = environment.baseUrl + '/api2/login';
|
||||||
|
export const LOGIN_VALIDATE_TOKEN = '';
|
||||||
|
export const EMAIL_URL = environment.baseUrl + "/api2/email";
|
||||||
|
export const RANDOM_VERSE_URL = "//www.kingjamesbibleonline.org/popular-bible-verses-widget.php";
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
export class Event{
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
startDate: Date;
|
||||||
|
endDate: Date;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EventResponse {
|
||||||
|
status: number;
|
||||||
|
events: Event[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SingleEventResponse {
|
||||||
|
status: number;
|
||||||
|
event: Event;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
export class Sermon{
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
date: Date;
|
||||||
|
uploadDate: Date;
|
||||||
|
description: string;
|
||||||
|
author: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SingleSermonResponse {
|
||||||
|
status: number;
|
||||||
|
sermon: Sermon;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MultipleSermonResponse {
|
||||||
|
status: number;
|
||||||
|
sermons: Sermon[];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Sermon } from '../interfaces/sermon';
|
||||||
|
import { AudioStates } from '../enum/audio-states';
|
||||||
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import { SERMON_MP3_BASE_URL } from '../constants/urls';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AudioPlayerService {
|
||||||
|
private audio: any = null;
|
||||||
|
private metaData: any = null;
|
||||||
|
|
||||||
|
public loading: boolean = true;
|
||||||
|
|
||||||
|
private stateChanged: Subject<{metaData:any,state:AudioStates,error:any}>;
|
||||||
|
|
||||||
|
public onAudioPlayerOpenClose: BehaviorSubject<boolean>;
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
this.stateChanged = new Subject<{metaData:any,state:AudioStates,error:any}>();
|
||||||
|
this.onAudioPlayerOpenClose = new BehaviorSubject<boolean>(false);
|
||||||
|
this.audio = new Audio();
|
||||||
|
this.audio.addEventListener("loadeddata",()=>this.doPlay());
|
||||||
|
this.audio.addEventListener("error",()=>this.error());
|
||||||
|
this.audio.addEventListener("ended",()=>this.ended());
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAudioPlayerOpen(isOpen: boolean){
|
||||||
|
this.onAudioPlayerOpenClose.next(isOpen);
|
||||||
|
}
|
||||||
|
|
||||||
|
play(src: string, metaData?: any): void{
|
||||||
|
src = SERMON_MP3_BASE_URL + src;
|
||||||
|
try{
|
||||||
|
if (typeof src === 'undefined' || src == null) return;
|
||||||
|
this.loading = true;
|
||||||
|
this.metaData = metaData;
|
||||||
|
this.stateChanged.next({metaData:this.metaData,state:AudioStates.Loading,error:null});
|
||||||
|
|
||||||
|
if (this.audio == null){
|
||||||
|
this.audio = new Audio(src);
|
||||||
|
} else {
|
||||||
|
this.audio.pause();
|
||||||
|
this.audio.src = src;
|
||||||
|
this.audio.load();
|
||||||
|
}
|
||||||
|
} catch(e){
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private doPlay(){
|
||||||
|
this.loading = false;
|
||||||
|
try{
|
||||||
|
if (this.audio.readyState >= 3){
|
||||||
|
this.stateChanged.next({metaData:this.metaData,state:AudioStates.Playing,error:null});
|
||||||
|
this.audio.play();
|
||||||
|
}
|
||||||
|
} catch(e){
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private error(){
|
||||||
|
this.stateChanged.next({metaData:this.metaData,state:AudioStates.Error,error:this.audio.error});
|
||||||
|
this.audio = null;
|
||||||
|
this.metaData = null;
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ended(){
|
||||||
|
this.stateChanged.next({metaData:this.metaData,state:AudioStates.Paused,error:null});
|
||||||
|
}
|
||||||
|
|
||||||
|
resume(): void{
|
||||||
|
if (this.audio == null) {
|
||||||
|
console.error("nothing to resume");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.audio.play();
|
||||||
|
this.stateChanged.next({metaData:this.metaData,state:AudioStates.Playing,error:null});
|
||||||
|
}
|
||||||
|
|
||||||
|
pause(): void{
|
||||||
|
if (this.audio == null) return;
|
||||||
|
this.audio.pause();
|
||||||
|
this.stateChanged.next({metaData:this.metaData,state:AudioStates.Paused,error:null});
|
||||||
|
}
|
||||||
|
|
||||||
|
stop(): void{
|
||||||
|
if (this.audio == null) return;
|
||||||
|
this.audio.pause();
|
||||||
|
this.stateChanged.next({metaData:this.metaData,state:AudioStates.Paused,error:null});
|
||||||
|
this.metaData = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup(): void{
|
||||||
|
this.audio = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setPosition(position: number): void{
|
||||||
|
if (this.audio == null) return;
|
||||||
|
this.audio.currentTime = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIsPlaying(): boolean{
|
||||||
|
if (this.audio == null) return false;
|
||||||
|
return !this.audio.paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentTime(): number{
|
||||||
|
if (this.audio == null) return null;
|
||||||
|
return this.audio.currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDuration(): number{
|
||||||
|
if (this.audio == null) return null;
|
||||||
|
return this.audio.duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMetaData(): any{
|
||||||
|
return this.metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
onStateChanged(): Observable<{metaData:any,state:AudioStates,error:any}>{
|
||||||
|
return this.stateChanged.asObservable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient, HttpResponse } from '@angular/common/http';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
import { RANDOM_VERSE_URL } from '../constants/urls';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class BibleVerseService {
|
||||||
|
constructor(private httpClient: HttpClient){}
|
||||||
|
|
||||||
|
randomVerse(){
|
||||||
|
//return this.http.get(RANDOM_VERSE_URL).map(this.gotData).catch(this.dataError);
|
||||||
|
}
|
||||||
|
|
||||||
|
gotData(res: Response){
|
||||||
|
console.log(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { throwError } from 'rxjs';
|
||||||
|
import { catchError } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { EMAIL_URL } from '../constants/urls';
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EmailService {
|
||||||
|
|
||||||
|
constructor(private httpClient: HttpClient){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sendEmail(fromName: string,
|
||||||
|
fromEmail: string,
|
||||||
|
fromPhone: string,
|
||||||
|
message: string,
|
||||||
|
hp: string){
|
||||||
|
|
||||||
|
let body = {
|
||||||
|
name: fromName,
|
||||||
|
email: fromEmail,
|
||||||
|
phone: fromPhone,
|
||||||
|
message: message,
|
||||||
|
hp: hp
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.httpClient.post(EMAIL_URL, body, {withCredentials:true})
|
||||||
|
.pipe(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}`);
|
||||||
|
}
|
||||||
|
// return an observable with a user-facing error message
|
||||||
|
return throwError(
|
||||||
|
'Something bad happened; please try again later.');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { Observable, throwError } from 'rxjs';
|
||||||
|
import { catchError, tap, map } from 'rxjs/operators';
|
||||||
|
import { Event, EventResponse, SingleEventResponse } from '../interfaces/event';
|
||||||
|
|
||||||
|
import { EVENTS_BY_PAGE_URL,
|
||||||
|
EVENT_BY_ID,
|
||||||
|
EVENTS_ADD_URL,
|
||||||
|
EVENTS_DELETE_BY_ID_URL } from '../constants/urls';
|
||||||
|
import { getBodyNode } from '@angular/animations/browser/src/render/shared';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EventService {
|
||||||
|
|
||||||
|
constructor(private httpClient: HttpClient){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getEvents(page: number): Observable<EventResponse> {
|
||||||
|
let url = EVENTS_BY_PAGE_URL + page + "?pageSize=" + 10;
|
||||||
|
return this.httpClient.get<EventResponse>(url)
|
||||||
|
.pipe(tap(e => this.setMultipleEventDates(e)),
|
||||||
|
catchError(this.handleError));
|
||||||
|
};
|
||||||
|
|
||||||
|
getSingleEvent(id: Number): Observable<SingleEventResponse>{
|
||||||
|
let url = EVENT_BY_ID + id;
|
||||||
|
return this.httpClient.get<SingleEventResponse>(url).pipe(tap(e => this.setSingleEventDates(e)), catchError(this.handleError));
|
||||||
|
};
|
||||||
|
|
||||||
|
setEventDates(event: Event): Event {
|
||||||
|
event.startDate = new Date(event.startDate);
|
||||||
|
event.endDate = new Date(event.endDate);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSingleEventDates(event : SingleEventResponse) : SingleEventResponse {
|
||||||
|
event.event = this.setEventDates(event.event);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
setMultipleEventDates(event: EventResponse) : EventResponse {
|
||||||
|
event.events.forEach(e => {
|
||||||
|
e = this.setEventDates(e);
|
||||||
|
});
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
addEvent(event: Event){
|
||||||
|
let fd = new FormData();
|
||||||
|
fd.append("title",event.title);
|
||||||
|
fd.append("description",event.description);
|
||||||
|
fd.append("startDate",new Date(event.startDate).getTime().toString()); //Pass date as milliseconds since 1970
|
||||||
|
fd.append("endDate",new Date(event.endDate).getTime().toString()); //Pass date as milliseconds since 1970
|
||||||
|
fd.append("timezoneOffset",new Date().getTimezoneOffset().toString());
|
||||||
|
|
||||||
|
return this.httpClient.post(EVENTS_ADD_URL, fd, {withCredentials:true}).pipe(catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteEvent(eventId: number){
|
||||||
|
let ro = {
|
||||||
|
body: {"id":eventId},
|
||||||
|
withCredentials: true
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.httpClient.delete(EVENTS_DELETE_BY_ID_URL, ro).pipe(catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
toEvent(json: any): Event{
|
||||||
|
return {
|
||||||
|
id: json.id,
|
||||||
|
title: json.title,
|
||||||
|
startDate: new Date(json.startDate),
|
||||||
|
endDate: new Date(json.endDate),
|
||||||
|
description: json.description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleError(error: HttpErrorResponse) {
|
||||||
|
console.error(error);
|
||||||
|
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}`);
|
||||||
|
}
|
||||||
|
// return an observable with a user-facing error message
|
||||||
|
return throwError(
|
||||||
|
'Something bad happened; please try again later.');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
|
import { Observable, Subject, throwError, of } from 'rxjs';
|
||||||
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { LOGIN_URL } from '../constants/urls';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LoginService {
|
||||||
|
private loggedIn: boolean = false;
|
||||||
|
private onChange: Subject<{isLoggedIn: boolean}>;
|
||||||
|
private lastLoginCheck: Date;
|
||||||
|
private options: {};
|
||||||
|
|
||||||
|
constructor(private httpClient: HttpClient){
|
||||||
|
this.options = {
|
||||||
|
withCredentials: true
|
||||||
|
};
|
||||||
|
this.lastLoginCheck = new Date();
|
||||||
|
this.lastLoginCheck.setHours(this.lastLoginCheck.getHours() - 2);
|
||||||
|
this.onChange = new Subject<{isLoggedIn: boolean}>();
|
||||||
|
}
|
||||||
|
|
||||||
|
login(username: string, password: string){
|
||||||
|
return this.httpClient.post(LOGIN_URL, {userName: username, password: password}, this.options).pipe(catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoggedIn(fromServer: boolean = false){
|
||||||
|
var now = new Date();
|
||||||
|
var hours = Math.abs(now.valueOf() - this.lastLoginCheck.valueOf()) / 36e5;
|
||||||
|
if (hours > 0.75 || fromServer === true){
|
||||||
|
return this.httpClient.post(LOGIN_URL + "/isloggedin",{},this.options)
|
||||||
|
.pipe(map((d:any) => {
|
||||||
|
let is = d.loggedIn === true;
|
||||||
|
this.loggedIn = is;
|
||||||
|
this.lastLoginCheck = new Date();
|
||||||
|
this.onChange.next({isLoggedIn: this.loggedIn});
|
||||||
|
return this.loggedIn;
|
||||||
|
}),
|
||||||
|
catchError(this.handleError));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
let val = this.loggedIn;
|
||||||
|
return of(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLogin(): Observable<{isLoggedIn: boolean}>{
|
||||||
|
return this.onChange.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
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}`);
|
||||||
|
}
|
||||||
|
// return an observable with a user-facing error message
|
||||||
|
return throwError(
|
||||||
|
'Something bad happened; please try again later.');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient, HttpErrorResponse, HttpRequest } from '@angular/common/http';
|
||||||
|
|
||||||
|
import { Observable, throwError } from 'rxjs';
|
||||||
|
import { catchError, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { Sermon, MultipleSermonResponse, SingleSermonResponse } from '../interfaces/sermon';
|
||||||
|
import { SERMONS_BY_ID,
|
||||||
|
SERMONS_BY_PAGE_URL,
|
||||||
|
SERMON_MP3_BASE_URL,
|
||||||
|
SERMONS_BY_SEARCH_URL,
|
||||||
|
SERMON_ADD_URL,
|
||||||
|
SERMON_DELETE_URL,
|
||||||
|
SERMON_UPDATE_URL } from '../constants/urls';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SermonService {
|
||||||
|
private pageSize: number = 10;
|
||||||
|
|
||||||
|
constructor(private httpClient: HttpClient){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getSermons(count: number): Observable<MultipleSermonResponse> {
|
||||||
|
let url = SERMONS_BY_PAGE_URL + 1 + "?pageSize=" + 5;
|
||||||
|
return this.httpClient.get<MultipleSermonResponse>(url).pipe(tap(e => this.setMultipleDates(e)), catchError(this.handleError));
|
||||||
|
};
|
||||||
|
|
||||||
|
getSermonsByPage(page: number): Observable<MultipleSermonResponse>{
|
||||||
|
let url = SERMONS_BY_PAGE_URL + page + "?pageSize=" + this.pageSize;
|
||||||
|
return this.httpClient.get<MultipleSermonResponse>(url).pipe(tap(e => this.setMultipleDates(e)), catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
getSermonById(id: number): Observable<SingleSermonResponse>{
|
||||||
|
let url = SERMONS_BY_ID + id + "?pageSize=" + this.pageSize;
|
||||||
|
return this.httpClient.get<SingleSermonResponse>(url).pipe(tap(e => this.setSingleDate(e)), catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
searchSermons(searchTerm: string, page: number): Observable<MultipleSermonResponse>{
|
||||||
|
let url = SERMONS_BY_SEARCH_URL + "?searchTerm=" + searchTerm + "&page=" + page + "&pageSize=" + this.pageSize;
|
||||||
|
return this.httpClient.get<MultipleSermonResponse>(url).pipe(tap(e => this.setMultipleDates(e)), catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
addSermon(sermon: Sermon, sermonFile: File){
|
||||||
|
let fd = new FormData();
|
||||||
|
fd.append("title",sermon.title);
|
||||||
|
fd.append("description",sermon.description);
|
||||||
|
fd.append("date",new Date(sermon.date).getTime().toString()); //Pas date as milliseconds since 1970
|
||||||
|
fd.append("author",sermon.author);
|
||||||
|
fd.append("file",sermonFile);
|
||||||
|
fd.append("timezoneOffset",new Date().getTimezoneOffset().toString());
|
||||||
|
const req = new HttpRequest('POST', SERMON_ADD_URL, fd, {
|
||||||
|
reportProgress: true,
|
||||||
|
withCredentials: true
|
||||||
|
});
|
||||||
|
return this.httpClient.request(req).pipe(
|
||||||
|
catchError(this.handleError)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSermon(sermon: Sermon){
|
||||||
|
let fd = new FormData();
|
||||||
|
fd.append("id",sermon.id.toString());
|
||||||
|
fd.append("title",sermon.title);
|
||||||
|
fd.append("description",sermon.description);
|
||||||
|
fd.append("date",new Date(sermon.date).toUTCString());
|
||||||
|
fd.append("author",sermon.author);
|
||||||
|
fd.append("timezoneOffset",new Date().getTimezoneOffset().toString());
|
||||||
|
return this.httpClient.put<Sermon>(SERMON_UPDATE_URL,fd,{withCredentials:true})
|
||||||
|
.pipe(catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
deleteSermon(sermonId: number){
|
||||||
|
let options = {
|
||||||
|
withCredentials: true,
|
||||||
|
body: {
|
||||||
|
"id" : sermonId
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return this.httpClient.delete(SERMON_DELETE_URL,options)
|
||||||
|
.pipe(catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
|
setSingleDate(e : SingleSermonResponse): SingleSermonResponse {
|
||||||
|
e.sermon = this.setDates(e.sermon);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
setMultipleDates(e : MultipleSermonResponse) : MultipleSermonResponse {
|
||||||
|
e.sermons.forEach(s => {
|
||||||
|
s = this.setDates(s);
|
||||||
|
});
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDates(sermon: Sermon): Sermon {
|
||||||
|
sermon.date = new Date(sermon.date);
|
||||||
|
sermon.uploadDate = new Date(sermon.uploadDate);
|
||||||
|
return sermon;
|
||||||
|
}
|
||||||
|
|
||||||
|
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}`);
|
||||||
|
}
|
||||||
|
// return an observable with a user-facing error message
|
||||||
|
return throwError(
|
||||||
|
'Something bad happened; please try again later.');
|
||||||
|
};
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
|
|
@ -0,0 +1,11 @@
|
||||||
|
# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
|
||||||
|
# For additional information regarding the format and rule options, please see:
|
||||||
|
# https://github.com/browserslist/browserslist#queries
|
||||||
|
#
|
||||||
|
# For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
|
||||||
|
|
||||||
|
> 0.5%
|
||||||
|
last 2 versions
|
||||||
|
Firefox ESR
|
||||||
|
not dead
|
||||||
|
not IE 9-11
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
export const environment = {
|
||||||
|
production: true,
|
||||||
|
baseUrl: ""
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// This file can be replaced during build by using the `fileReplacements` array.
|
||||||
|
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||||
|
// The list of file replacements can be found in `angular.json`.
|
||||||
|
|
||||||
|
export const environment = {
|
||||||
|
production: false,
|
||||||
|
baseUrl: "http://localhost:25776"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For easier debugging in development mode, you can import the following file
|
||||||
|
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||||
|
*
|
||||||
|
* This import should be commented out in production mode because it will have a negative impact
|
||||||
|
* on performance if an error is thrown.
|
||||||
|
*/
|
||||||
|
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- V2 -->
|
||||||
|
<base href="/">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Old Fashion Baptist Church</title>
|
||||||
|
|
||||||
|
<!-- Google Analytics -->
|
||||||
|
<!-- Global Site Tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-107601801-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
</script>
|
||||||
|
<!---->
|
||||||
|
|
||||||
|
<!-- Favicons -->
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/web-app-files/apple-touch-icon.png?v=LbWKNzlwGb">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/web-app-files/favicon-32x32.png?v=LbWKNzlwGb">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/web-app-files/favicon-16x16.png?v=LbWKNzlwGb">
|
||||||
|
<link rel="manifest" href="/web-app-files/manifest.json?v=LbWKNzlwGb">
|
||||||
|
<link rel="mask-icon" href="/web-app-files/safari-pinned-tab.svg?v=LbWKNzlwGb" color="#00bcd4">
|
||||||
|
<link rel="shortcut icon" href="/web-app-files/favicon.ico?v=LbWKNzlwGb">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="Old Fashion Baptist">
|
||||||
|
<meta name="application-name" content="Old Fashion Baptist">
|
||||||
|
<meta name="msapplication-config" content="/web-app-files/browserconfig.xml?v=LbWKNzlwGb">
|
||||||
|
<meta name="theme-color" content="#00bcd4">
|
||||||
|
<!-- End Favicons -->
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.loader-background{
|
||||||
|
background-color: rgb(0, 188, 212);
|
||||||
|
position: fixed;
|
||||||
|
left:0px;
|
||||||
|
top:0px;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
color: #ffffff;
|
||||||
|
margin: 40px auto;
|
||||||
|
position: relative;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
.loader-small{
|
||||||
|
color: #ffffff;
|
||||||
|
margin: 70px auto;
|
||||||
|
position: relative;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.address{
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.service-times{
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 5px auto;
|
||||||
|
}
|
||||||
|
.ie{
|
||||||
|
padding: 15px;
|
||||||
|
background-color: red;
|
||||||
|
color: white;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
.ie-small{
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<app-root>
|
||||||
|
<div class="loader-background">
|
||||||
|
<!--[if IE]>
|
||||||
|
<div class="ie">Oh No! Looks like your browser is pretty outdated so our site may not work correctly.
|
||||||
|
<p class="ie-small">Please consider updating</p>
|
||||||
|
</div>
|
||||||
|
<![endif]-->
|
||||||
|
<div class="loader">Old Fashion Baptist<p class="address">5003 Wynne Ave | Butte, MT 59701</p></div>
|
||||||
|
<!--[if !IE]><!-->
|
||||||
|
<div class="loader-small">Please Wait...</div>
|
||||||
|
<!--<![endif]-->
|
||||||
|
<p class="service-times"><b>Service Times</b></p>
|
||||||
|
<p class="service-times">Sunday School: 10 AM</p>
|
||||||
|
<p class="service-times">Sunday Morning: 11 AM</p>
|
||||||
|
<p class="service-times">Sunday Evening: 7 PM</p>
|
||||||
|
<p class="service-times">Wednesday Evening: 7 PM</p>
|
||||||
|
</div>
|
||||||
|
</app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
basePath: '',
|
||||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||||
|
plugins: [
|
||||||
|
require('karma-jasmine'),
|
||||||
|
require('karma-chrome-launcher'),
|
||||||
|
require('karma-jasmine-html-reporter'),
|
||||||
|
require('karma-coverage-istanbul-reporter'),
|
||||||
|
require('@angular-devkit/build-angular/plugins/karma')
|
||||||
|
],
|
||||||
|
client: {
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
coverageIstanbulReporter: {
|
||||||
|
dir: require('path').join(__dirname, '../coverage'),
|
||||||
|
reports: ['html', 'lcovonly', 'text-summary'],
|
||||||
|
fixWebpackSourcePaths: true
|
||||||
|
},
|
||||||
|
reporters: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { enableProdMode } from '@angular/core';
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
import { AppModule } from './app/app.module';
|
||||||
|
import { environment } from './environments/environment';
|
||||||
|
|
||||||
|
if (environment.production) {
|
||||||
|
enableProdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||||
|
* You can add your own extra polyfills to this file.
|
||||||
|
*
|
||||||
|
* This file is divided into 2 sections:
|
||||||
|
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||||
|
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||||
|
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||||
|
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||||
|
*
|
||||||
|
* Learn more in https://angular.io/guide/browser-support
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* BROWSER POLYFILLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** IE9, IE10, IE11, and Chrome <55 requires all of the following polyfills.
|
||||||
|
* This also includes Android Emulators with older versions of Chrome and Google Search/Googlebot
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'core-js/es6/symbol';
|
||||||
|
import 'core-js/es6/object';
|
||||||
|
import 'core-js/es6/function';
|
||||||
|
import 'core-js/es6/parse-int';
|
||||||
|
import 'core-js/es6/parse-float';
|
||||||
|
import 'core-js/es6/number';
|
||||||
|
import 'core-js/es6/math';
|
||||||
|
import 'core-js/es6/string';
|
||||||
|
import 'core-js/es6/date';
|
||||||
|
import 'core-js/es6/array';
|
||||||
|
import 'core-js/es6/regexp';
|
||||||
|
import 'core-js/es6/map';
|
||||||
|
import 'core-js/es6/weak-map';
|
||||||
|
import 'core-js/es6/set';
|
||||||
|
|
||||||
|
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
||||||
|
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||||
|
|
||||||
|
/** IE10 and IE11 requires the following for the Reflect API. */
|
||||||
|
// import 'core-js/es6/reflect';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Animations `@angular/platform-browser/animations`
|
||||||
|
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
|
||||||
|
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
|
||||||
|
*/
|
||||||
|
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||||
|
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||||
|
* because those flags need to be set before `zone.js` being loaded, and webpack
|
||||||
|
* will put import in the top of bundle, so user need to create a separate file
|
||||||
|
* in this directory (for example: zone-flags.ts), and put the following flags
|
||||||
|
* into that file, and then add the following code before importing zone.js.
|
||||||
|
* import './zone-flags.ts';
|
||||||
|
*
|
||||||
|
* The flags allowed in zone-flags.ts are listed here.
|
||||||
|
*
|
||||||
|
* The following flags will work for all browsers.
|
||||||
|
*
|
||||||
|
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||||
|
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||||
|
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||||
|
*
|
||||||
|
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||||
|
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||||
|
*
|
||||||
|
* (window as any).__Zone_enable_cross_context_check = true;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* Zone JS is required by default for Angular itself.
|
||||||
|
*/
|
||||||
|
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* APPLICATION IMPORTS
|
||||||
|
*/
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
|
||||||
|
|
||||||
|
*{
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
height: calc(100% - 50px); /*Less 50 px for height of static header*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.red{
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*MATERIAL FONT FOR ICONS*/
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(./assets/fonts/MaterialIcons-Regular.eot); /* For IE6-8 */
|
||||||
|
src: local('Material Icons'),
|
||||||
|
local('MaterialIcons-Regular'),
|
||||||
|
url(./assets/fonts/MaterialIcons-Regular.woff2) format('woff2'),
|
||||||
|
url(./assets/fonts/MaterialIcons-Regular.woff) format('woff'),
|
||||||
|
url(./assets/fonts/MaterialIcons-Regular.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icon {
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 24px; /* Preferred icon size */
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 1;
|
||||||
|
text-transform: none;
|
||||||
|
letter-spacing: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
white-space: nowrap;
|
||||||
|
direction: ltr;
|
||||||
|
|
||||||
|
/* Support for all WebKit browsers. */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
/* Support for Safari and Chrome. */
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
|
||||||
|
/* Support for Firefox. */
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
/* Support for IE. */
|
||||||
|
font-feature-settings: 'liga';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* END MATERIAL FONT ICONS*/
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
|
import 'zone.js/dist/zone-testing';
|
||||||
|
import { getTestBed } from '@angular/core/testing';
|
||||||
|
import {
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting
|
||||||
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
|
declare const require: any;
|
||||||
|
|
||||||
|
// First, initialize the Angular testing environment.
|
||||||
|
getTestBed().initTestEnvironment(
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting()
|
||||||
|
);
|
||||||
|
// Then we find all the tests.
|
||||||
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
|
// And load the modules.
|
||||||
|
context.keys().map(context);
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/app",
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"test.ts",
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"test.ts",
|
||||||
|
"polyfills.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"extends": "../tslint.json",
|
||||||
|
"rules": {
|
||||||
|
"directive-selector": [
|
||||||
|
true,
|
||||||
|
"attribute",
|
||||||
|
"app",
|
||||||
|
"camelCase"
|
||||||
|
],
|
||||||
|
"component-selector": [
|
||||||
|
true,
|
||||||
|
"element",
|
||||||
|
"app",
|
||||||
|
"kebab-case"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"compileOnSave": false,
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./",
|
||||||
|
"outDir": "./dist/out-tsc",
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": false,
|
||||||
|
"module": "es2015",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"importHelpers": true,
|
||||||
|
"target": "es5",
|
||||||
|
"typeRoots": [
|
||||||
|
"node_modules/@types"
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es2018",
|
||||||
|
"dom"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
{
|
||||||
|
"rulesDirectory": [
|
||||||
|
"codelyzer"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"arrow-return-shorthand": true,
|
||||||
|
"callable-types": true,
|
||||||
|
"class-name": true,
|
||||||
|
"comment-format": [
|
||||||
|
true,
|
||||||
|
"check-space"
|
||||||
|
],
|
||||||
|
"curly": true,
|
||||||
|
"deprecation": {
|
||||||
|
"severity": "warn"
|
||||||
|
},
|
||||||
|
"eofline": true,
|
||||||
|
"forin": true,
|
||||||
|
"import-blacklist": [
|
||||||
|
true,
|
||||||
|
"rxjs/Rx"
|
||||||
|
],
|
||||||
|
"import-spacing": true,
|
||||||
|
"indent": [
|
||||||
|
true,
|
||||||
|
"spaces"
|
||||||
|
],
|
||||||
|
"interface-over-type-literal": true,
|
||||||
|
"label-position": true,
|
||||||
|
"max-line-length": [
|
||||||
|
true,
|
||||||
|
140
|
||||||
|
],
|
||||||
|
"member-access": false,
|
||||||
|
"member-ordering": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"order": [
|
||||||
|
"static-field",
|
||||||
|
"instance-field",
|
||||||
|
"static-method",
|
||||||
|
"instance-method"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-arg": true,
|
||||||
|
"no-bitwise": true,
|
||||||
|
"no-console": [
|
||||||
|
true,
|
||||||
|
"debug",
|
||||||
|
"info",
|
||||||
|
"time",
|
||||||
|
"timeEnd",
|
||||||
|
"trace"
|
||||||
|
],
|
||||||
|
"no-construct": true,
|
||||||
|
"no-debugger": true,
|
||||||
|
"no-duplicate-super": true,
|
||||||
|
"no-empty": false,
|
||||||
|
"no-empty-interface": true,
|
||||||
|
"no-eval": true,
|
||||||
|
"no-inferrable-types": [
|
||||||
|
true,
|
||||||
|
"ignore-params"
|
||||||
|
],
|
||||||
|
"no-misused-new": true,
|
||||||
|
"no-non-null-assertion": true,
|
||||||
|
"no-redundant-jsdoc": true,
|
||||||
|
"no-shadowed-variable": true,
|
||||||
|
"no-string-literal": false,
|
||||||
|
"no-string-throw": true,
|
||||||
|
"no-switch-case-fall-through": true,
|
||||||
|
"no-trailing-whitespace": true,
|
||||||
|
"no-unnecessary-initializer": true,
|
||||||
|
"no-unused-expression": true,
|
||||||
|
"no-use-before-declare": true,
|
||||||
|
"no-var-keyword": true,
|
||||||
|
"object-literal-sort-keys": false,
|
||||||
|
"one-line": [
|
||||||
|
true,
|
||||||
|
"check-open-brace",
|
||||||
|
"check-catch",
|
||||||
|
"check-else",
|
||||||
|
"check-whitespace"
|
||||||
|
],
|
||||||
|
"prefer-const": true,
|
||||||
|
"quotemark": [
|
||||||
|
true,
|
||||||
|
"single"
|
||||||
|
],
|
||||||
|
"radix": true,
|
||||||
|
"semicolon": [
|
||||||
|
true,
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"triple-equals": [
|
||||||
|
true,
|
||||||
|
"allow-null-check"
|
||||||
|
],
|
||||||
|
"typedef-whitespace": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"call-signature": "nospace",
|
||||||
|
"index-signature": "nospace",
|
||||||
|
"parameter": "nospace",
|
||||||
|
"property-declaration": "nospace",
|
||||||
|
"variable-declaration": "nospace"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"unified-signatures": true,
|
||||||
|
"variable-name": false,
|
||||||
|
"whitespace": [
|
||||||
|
true,
|
||||||
|
"check-branch",
|
||||||
|
"check-decl",
|
||||||
|
"check-operator",
|
||||||
|
"check-separator",
|
||||||
|
"check-type"
|
||||||
|
],
|
||||||
|
"no-output-on-prefix": true,
|
||||||
|
"use-input-property-decorator": true,
|
||||||
|
"use-output-property-decorator": true,
|
||||||
|
"use-host-property-decorator": true,
|
||||||
|
"no-input-rename": true,
|
||||||
|
"no-output-rename": true,
|
||||||
|
"use-life-cycle-interface": true,
|
||||||
|
"use-pipe-transform-interface": true,
|
||||||
|
"component-class-suffix": true,
|
||||||
|
"directive-class-suffix": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue