diff --git a/bit-badger-solutions/src/app/app-routing.module.ts b/bit-badger-solutions/src/app/app-routing.module.ts index dc86f8a..878656f 100644 --- a/bit-badger-solutions/src/app/app-routing.module.ts +++ b/bit-badger-solutions/src/app/app-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core' import { Routes, RouterModule } from '@angular/router' -import { ApplicationComponent } from './applications/application/application.component' +import { ApplicationComponent } from './applications/application.component' import { ApplicationListComponent } from './applications/application-list/application-list.component' import { HomeComponent } from './pages/home/home.component' import { InformationPublicizingComponent } from './pages/about/information-publicizing.component' diff --git a/bit-badger-solutions/src/app/applications/all-solutions-link.component.ts b/bit-badger-solutions/src/app/applications/all-solutions-link.component.ts new file mode 100644 index 0000000..2c65dc5 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/all-solutions-link.component.ts @@ -0,0 +1,13 @@ +import { Component, OnInit } from '@angular/core' + +@Component({ + selector: 'app-all-solutions-link', + template: `


« Back to All Solutions

` +}) +export class AllSolutionsLinkComponent implements OnInit { + + constructor() { } + + ngOnInit() { } + +} diff --git a/bit-badger-solutions/src/app/applications/app-item.ts b/bit-badger-solutions/src/app/applications/app-item.ts new file mode 100644 index 0000000..9caca43 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/app-item.ts @@ -0,0 +1,6 @@ +import { Type } from '@angular/core' + +/** An item representing an app */ +export class AppItem { + constructor(public name: string, public component: Type) { } +} diff --git a/bit-badger-solutions/src/app/applications/application-detail.directive.ts b/bit-badger-solutions/src/app/applications/application-detail.directive.ts new file mode 100644 index 0000000..e6f1bf8 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/application-detail.directive.ts @@ -0,0 +1,10 @@ +import { Directive, ViewContainerRef } from '@angular/core' + +@Directive({ + selector: '[app-application-detail]' +}) +export class ApplicationDetailDirective { + + constructor(public viewContainerRef: ViewContainerRef) { } + +} diff --git a/bit-badger-solutions/src/app/applications/application-header/application-header.component.html b/bit-badger-solutions/src/app/applications/application-header/application-header.component.html new file mode 100644 index 0000000..5a6a73b --- /dev/null +++ b/bit-badger-solutions/src/app/applications/application-header/application-header.component.html @@ -0,0 +1,10 @@ +

+ {{ app.name }}
+ + {{ app.url }} + {{ app.url }} +     + (Archive) + + +

diff --git a/bit-badger-solutions/src/app/applications/application-header/application-header.component.sass b/bit-badger-solutions/src/app/applications/application-header/application-header.component.sass new file mode 100644 index 0000000..86fc05b --- /dev/null +++ b/bit-badger-solutions/src/app/applications/application-header/application-header.component.sass @@ -0,0 +1,2 @@ +h1 + line-height: 1.6rem diff --git a/bit-badger-solutions/src/app/applications/application-header/application-header.component.ts b/bit-badger-solutions/src/app/applications/application-header/application-header.component.ts new file mode 100644 index 0000000..4c62377 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/application-header/application-header.component.ts @@ -0,0 +1,28 @@ +import { Component, OnInit, Input } from '@angular/core' + +import { App } from '../application.types' + +@Component({ + selector: 'app-application-header', + templateUrl: './application-header.component.html', + styleUrls: ['./application-header.component.sass'] +}) +export class ApplicationHeaderComponent implements OnInit { + + @Input() app: App + + constructor() { } + + ngOnInit() { } + + /** Whether to link to the app's URL */ + get linkToApp () { + return this.app.isActive || this.app.linkInactive + } + + /** Whether to link to an archive URL */ + get linkToArchive () { + return !this.app.isActive && !this.app.linkInactive && (this.app.archiveUrl > '') + } + +} diff --git a/bit-badger-solutions/src/app/applications/application-image/application-image.component.html b/bit-badger-solutions/src/app/applications/application-image/application-image.component.html new file mode 100644 index 0000000..7f8db5d --- /dev/null +++ b/bit-badger-solutions/src/app/applications/application-image/application-image.component.html @@ -0,0 +1 @@ + diff --git a/bit-badger-solutions/src/app/applications/application-image/application-image.component.sass b/bit-badger-solutions/src/app/applications/application-image/application-image.component.sass new file mode 100644 index 0000000..5941dd7 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/application-image/application-image.component.sass @@ -0,0 +1,5 @@ +aside + padding-left: 15px +aside img + border: dotted 1px darkgray + border-radius: 10px diff --git a/bit-badger-solutions/src/app/applications/application-image/application-image.component.ts b/bit-badger-solutions/src/app/applications/application-image/application-image.component.ts new file mode 100644 index 0000000..c4f6a3d --- /dev/null +++ b/bit-badger-solutions/src/app/applications/application-image/application-image.component.ts @@ -0,0 +1,29 @@ +import { Component, OnInit, Input } from '@angular/core' + +import { App } from '../application.types' + +@Component({ + selector: 'app-application-image', + templateUrl: './application-image.component.html', + styleUrls: ['./application-image.component.sass'] +}) +export class ApplicationImageComponent implements OnInit { + + @Input() app: App + + constructor() { } + + ngOnInit() { + } + + /** The link to the screenshot image */ + get imageLink () { + return `/assets/screenshots/${this.app.id}.png` + } + + /** The alt text for the screenshot image */ + get imageAlt () { + return `Screen shot for ${this.app.name}` + } + +} diff --git a/bit-badger-solutions/src/app/applications/application.component.ts b/bit-badger-solutions/src/app/applications/application.component.ts new file mode 100644 index 0000000..c45c9cd --- /dev/null +++ b/bit-badger-solutions/src/app/applications/application.component.ts @@ -0,0 +1,69 @@ +import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core' +import { ActivatedRoute } from '@angular/router' + +import { ApplicationService } from './application.service' +import { App } from './application.types' +import { AppItem } from './app-item' +import { ApplicationDetailDirective } from './application-detail.directive' +import { AppDetailComponent } from './solutions/app-detail.component' + +import { PrayerTrackerComponent } from './solutions/prayer-tracker.component' +import { VirtualPrayerRoomComponent } from './solutions/virtual-prayer-room.component' +import { BayVistaComponent } from './solutions/bay-vista.component' +import { CassyFianoComponent } from './solutions/cassy-fiano.component' +import { DrMelissaClouthierComponent } from './solutions/dr-melissa-clouthier.component' +import { EmeraldMountainChristianSchoolComponent } from './solutions/emerald-mountain-christian-school.component' +import { FutilityClosetComponent } from './solutions/futility-closet.component' +import { HardCorpsWifeComponent } from './solutions/hard-corps-wife.component' +import { LibertyPunditsComponent } from './solutions/liberty-pundits.component' + +@Component({ + selector: 'app-application', + template: '' +}) +export class ApplicationComponent implements OnInit { + + private apps = [ + new AppItem('bay-vista', BayVistaComponent), + new AppItem('cassy-fiano', CassyFianoComponent), + new AppItem('dr-melissa-clouthier', DrMelissaClouthierComponent), + new AppItem('emerald-mountain-christian-school', EmeraldMountainChristianSchoolComponent), + new AppItem('futility-closet', FutilityClosetComponent), + new AppItem('hard-corps-wife', HardCorpsWifeComponent), + new AppItem('liberty-pundits', LibertyPunditsComponent), + new AppItem('prayer-tracker', PrayerTrackerComponent), + new AppItem('virtual-prayer-room', VirtualPrayerRoomComponent) + ] + + @ViewChild(ApplicationDetailDirective, { static: true }) appDetail: ApplicationDetailDirective + + /** The app we're displaying */ + application: App + + constructor( + private componentFactoryResolver: ComponentFactoryResolver, + private appService: ApplicationService, + private route: ActivatedRoute + ) { } + + ngOnInit() { + this.route.params.subscribe(params => this.displayApp(params['appId'])) + } + + /** Dynamically load the app-ropriate component */ + displayApp(appId: string) { + const appComponent = this.apps.find(a => a.name === appId) + + const componentFactory = this.componentFactoryResolver.resolveComponentFactory(appComponent.component) + const viewContainerRef = this.appDetail.viewContainerRef + viewContainerRef.clear() + + const componentRef = viewContainerRef.createComponent(componentFactory) + this.appService.getApp(appId) + .subscribe(app => { + (componentRef.instance).app = app + this.application = app + }) + } + +} diff --git a/bit-badger-solutions/src/app/applications/application.data.ts b/bit-badger-solutions/src/app/applications/application.data.ts index d4f0ca9..89baef7 100644 --- a/bit-badger-solutions/src/app/applications/application.data.ts +++ b/bit-badger-solutions/src/app/applications/application.data.ts @@ -13,33 +13,9 @@ bayVista.categoryId = Category.STATIC bayVista.frontPageText = 'Biloxi, Mississippi' bayVista.frontPageOrder = 1 bayVista.indexText = 'Southern Baptist church in Biloxi, Mississippi' -bayVista.paragraphs = [ - `Bay Vista Baptist Church has served the spiritual needs of Mississippi’s Gulf Coast for decades. They emphasize - serving their community as well; they were a hub for FEMA - during Hurricane Katrina relief and recovery efforts, and they are a relay point for each year’s - Operation Christmas Child - campaign. As of late 2013, the authors of their current website were no longer around, and no one could get to the - site to update it. We proposed setting up a site based on WordPress, where multiple people could have the ability to - maintain the site, reducing the risk of that happening again. We also mentioned that such a site could also serve a - sermon podcast feed, increasing the reach of their ministry.` -] -bayVista.activities = [ - new Activity('What We Did (2014)', - `We manually downloaded all the publically-accessible parts of their old site, and used that content to create a - WordPress-based site, updating a few outdated items along the way. We also established a podcast feed for their - sermons. A few months after initially setting up the site, we updated the theme to be more mobile-friendly.`), - new Activity('What We Did (2016)', - `In the nearly three years since we had set up the site, we were the only ones updating it. We had recently migrated - some older blogs to use a static site generator and were impressed with the performance gains. We converted their - site, to include writing a custom template to support the podcast feed; it is now generated along with the rest of - the site.`), - new Activity('What We Still Do', - `Bit Badger Solutions hosts this site; we also host the church e-mail accounts, and publish sermons to their podcast - feed weekly.`) -] bayVista.techStack = [ new Technology('Hexo', 'static site generation'), - new Technology('Azure', 'podcast file storage') + new Technology('Azure', 'podcast file storage and automated builds') ] /** Cassy Fiano */ @@ -47,23 +23,6 @@ const cassyFiano = new App('cassy-fiano', 'Cassy Fiano', 'http://www.cassyfiano. cassyFiano.isActive = false cassyFiano.categoryId = Category.WORDPRESS cassyFiano.indexText = 'A “rising star” conservative blogger' -cassyFiano.paragraphs = [ - `Cassy Fiano (now Cassy Chesser) began blogging back in 2007 on Blogger. She worked hard to network with other - bloggers, and wrote prolifically. As she approached the end of her first year of blogging, she was about to outgrow - Blogger. She asked in a blog post if anyone had experience with Movable Type, the platform used by another blog to - which she contributed. I replied that I did not, but that I had experience with WordPress.` -] -cassyFiano.activities = [ - new Activity('What We Did (2008)', - `We assisted her with finding a theme, and customized that theme to contain the same sidebar elements as her current - Blogger theme. We modified her old Blogger template to send people to her new blog (using redirection) after - displaying a note that the blog had moved.`), - new Activity('What We Did (2012)', - `In July 2012, we began hosting the site, as well as continuing support for theme updates. This joined her military - wife blog Hard Corps Wife, - which we had begun hosting in mid-2011.`), - new Activity('What We Still Do', 'Cassy formally decommissioned this site in early 2014.') -] cassyFiano.techStack = [ new Technology('WordPress', 'blogging (with a custom theme)') ] /** Daniel J. Summers */ @@ -80,25 +39,6 @@ drMelissaClouthier.categoryId = Category.WORDPRESS drMelissaClouthier.frontPageText = 'Information Pollination' drMelissaClouthier.frontPageOrder = 1 drMelissaClouthier.indexText = 'Politics, health, podcasts and more' -drMelissaClouthier.paragraphs = [ - `Dr. Melissa Clouthier saw our work with - Cassy’s site, and asked us to - help her move off Blogger as well. Melissa blogs from the political right, but also covers health issues and social - media. She had been blogging for a several years, and wanted to bring her old content with her to her new site.` -] -drMelissaClouthier.activities = [ - new Activity('What We Did (2009)', - `We created a custom theme based on another site, and developed graphics to complement that theme. We also imported - the content from her Blogger site into the WordPress site, and created a featured content template for the front - page.`), - new Activity('What We Did (2018)', - `Melissa decommissioned her site; we took final snapshots of the information there, then assisted with shutting it - down.`) -] -drMelissaClouthier.footnotes = [ - `(NOTE: The thumbnail of the site represents a new skin on the original theme; while the theme is the same, Bit - Badger Solutions did not create the graphics.)` -] drMelissaClouthier.techStack = [ new Technology('WordPress', 'blogging (with a custom theme)') ] /** Emerald Mountain Christian School */ @@ -107,28 +47,6 @@ const emcs = new App('emerald-mountain-christian-school', 'Emerald Mountain Chri emcs.isActive = false emcs.linkInactive = true emcs.indexText = 'Classical, Christ-centered education near Wetumpka, Alabama' -emcs.paragraphs = [ - `Emerald Mountain Christian School is a private Christian school founded over 50 years ago. They use the Principle - Approach®, which emphasizes research, reasoning, relating, and recording to help students synthesize the - information they learn, rather than just requiring rote memorization. More information about the school’s rich - history can be found on their site.` -] -emcs.activities = [ - new Activity('What We Did (2004)', - `They had a website with very basic information and very little styling. We developed a theme (the one in the - thumbnail), based in large part on the design of their printed materials, and they approved the design. Initially, - the site only contained the content from their previous site. We then put their school calendar of events up on - the site, where parents could find the dates for upcoming events. Finally, we put all the material from their - Parent Information Packet online, which helped prospective families learn more about the school before visiting - it.`), - new Activity('What We Did (2011)', - `The underlying engine of the basic website was switched from PHP to an ASP MVC web application, and the back-end - database was switched from MySQL to a PostgreSQL database.`), - new Activity('What We Did (2013)', - `We passed off the content and hosting of the site to a new maintainer. They have since redesigned it; it is - accessible via the URL above, and at - EMCSpatriots.org.`) -] emcs.techStack = [ new Technology('ASP.NET MVC', 'page generation and interactivity'), new Technology('PostgreSQL', 'data storage') @@ -140,20 +58,6 @@ futilityCloset.categoryId = Category.WORDPRESS futilityCloset.frontPageText = 'An idler’s miscellany of compendious amusements' futilityCloset.frontPageOrder = 2 futilityCloset.indexText = 'An idler’s miscellany of compendious amusements' -futilityCloset.paragraphs = [ - `Futility Closet exists as a place to give people a break from the dullness of work, by providing puzzles, anecdotes, - and more. It began on a shared host, but was growing too large and popular for that platform.` -] -futilityCloset.activities = [ - new Activity('What We Did', - `We determined what the traffic requirements and size of the blog were, then made some recommendations. Greg Ross, - the site author, decided on one of our recommendations. He had backups of the existing database, so we were able to - set up a server and restore the data onto that new server. We configured WordPress and locked down the server, and - this blog was moved quickly.`), - new Activity('What We Still Do', - `Bit Badger Solutions still hosts Futility Closet, ensuring that the underlying server receives performance and - security upgrades, monitoring site performance, and maintaining regular backups.`) -] const fcQuote = new Quote('Greg Ross', 'Futility Closet') fcQuote.full = `Bit Badger Solutions has been an absolute godsend for Futility Closet. We have been with them since 2010, initially @@ -178,17 +82,6 @@ const hardCorpsWife = new App('hard-corps-wife', 'Hard Corps Wife', 'http://www. hardCorpsWife.isActive = false hardCorpsWife.categoryId = Category.WORDPRESS hardCorpsWife.indexText = 'Cassy’s life as a Marine wife' -hardCorpsWife.paragraphs = [ - `Capitalizing on the growth from her Cassy Fiano blog, Cassy (now Chesser) began a separate blog in which she could - chronicle her experience as a military spouse.` -] -hardCorpsWife.activities = [ - new Activity('What We Did', - 'We customized the header and sidebar of the theme, and set up the hardcorpswife.com domain.'), - new Activity('What We Still Do', - `In 2013, Cassy shifted priorities and closed this site down. She can still be found at other places around the - web.`) -] hardCorpsWife.techStack = [ new Technology('WordPress', 'blogging') ] /** Liberty Pundits */ @@ -196,30 +89,6 @@ const libertyPundits = new App('liberty-pundits', 'Liberty Pundits', 'http://lib libertyPundits.isActive = false libertyPundits.categoryId = Category.WORDPRESS libertyPundits.indexText = 'The home for conservatives' -libertyPundits.paragraphs = [ - `At its founding, Liberty Pundits was a joint venture by 3 established bloggers (Melissa Clouthier, Bill Dupray, and - Clyde Middleton) that, in their words, was aimed at becoming the new home for conservatives on the Internet. With the - three of them all being prolific bloggers in their own right, and the help of many contributors, Liberty Pundits was - a bustling hub of information.` -] -libertyPundits.activities = [ - new Activity('What We Did', - `Bill and Clyde had been part of Patriot Room, an already-recognized powerhouse, and their desire was for Liberty - Pundits to contain the content that they had contributed to Patriot Room. The technical lead on that blog had moved - on, so we did some divining of what was there. Once we deduced the current setup, we obtained the data from that - site, determined how it would need to be manipulated to become part of a WordPress blog, then accomplished the data - migration. Initially, this was deployed on the same shared hosting account where LibertyPundits.com, their podcast - distribution site, already resided. The site’s traffic quickly overwhelmed that solution. They then were - moved by their host to a VPS, which performed moderately better, but - still had quite a few issues, mostly related to the site’s traffic volume. We recommended a new server - configuration, including migrating from a fully-featured web server to a more lightweight web server, along with - caching, and configured that server. This configuration eliminated the bottlenecks, and enabled them to have - several 100,000+ hit days with no appreciable slowdowns.`), - new Activity('What We Still Do', - `Bit Badger Solutions maintained the server, keeping it current with performance and security upgrades. We also - provided support to the primary 3 bloggers, when they had questions about WordPress or how the site was performing. - The site closed in August of 2011, as the primary authors moved on to other endeavors.`) -] libertyPundits.techStack = [ new Technology('WordPress', 'blogging'), new Technology('Custom software', 'data migration') @@ -539,25 +408,6 @@ theSharkTank.activities = [ const vpr = new App('virtual-prayer-room', 'Virtual Prayer Room', 'https://virtualprayerroom.us') vpr.isActive = false vpr.indexText = 'Gives prayer warriors access to requests from wherever they may be, and sends them daily updates' -vpr.paragraphs = [ - `Many churches have prayer rooms – rooms set aside for people to come in to pray. Hoffmantown Church in - Albuquerque, New Mexico was one of these churches. However, they had seen the use of this physical prayer room - dwindling over the years. People had become less willing to drive to the church, especially at night, and security - became an issue as well; either prayer warriors had to know how to disable the security system, or the church would - have to remain unlocked.`, - `Having seen our work with the Not So Extreme Makeover: Community - Edition, the church contacted us to see if something similar could be developed to help their prayer ministry. - The resulting application that was developed extended the prayer room to wherever the prayer warrior can get an - Internet connection! Prayer warriors could enlist right from the site, and had to be approved. Requests and updates - were tracked by date/time, and warriors could record when they’ve prayed for a request from the site, or from - clicking a link in the daily e-mail they received with requests from their interest areas. As many prayer needs are - confidential, security and confidentiality were very important. Virtual Prayer Room ensured these by providing - varying security levels for prayer warriors and the ability to mark each request as confidential.`, - `In 2016, Hoffmantown Church elected to begin using another package for their prayer requests. While a few other - churches had expressed interest in it, none ultimately decided to use it; so, in 2017, Virtual Prayer Room was - officially decommissioned.` -] vpr.techStack = [ new Technology('Custom PHP code', 'the application'), new Technology('PostgreSQL', 'data storage') diff --git a/bit-badger-solutions/src/app/applications/application/application.component.html b/bit-badger-solutions/src/app/applications/application/application.component.html deleted file mode 100644 index f2796b8..0000000 --- a/bit-badger-solutions/src/app/applications/application/application.component.html +++ /dev/null @@ -1,35 +0,0 @@ - -
-

- {{ application.name }}
- - {{ application.url }} - {{ application.url }} -     - (Archive) - - -

-
- -
-

-
-

{{ act.heading }}

-

-
-
-

What They Say

-
-

-

- — {{ q.name }} - , {{ q.from }} -

-
-
-

-


« Back to All Solutions

-
-
-
diff --git a/bit-badger-solutions/src/app/applications/application/application.component.sass b/bit-badger-solutions/src/app/applications/application/application.component.sass deleted file mode 100644 index 8a12cfd..0000000 --- a/bit-badger-solutions/src/app/applications/application/application.component.sass +++ /dev/null @@ -1,21 +0,0 @@ -h1 - line-height: 1.6rem -.app-info - display: flex - flex-flow: row-reverse wrap - justify-content: center -aside - padding-left: 15px -aside img - border: dotted 1px darkgray - border-radius: 10px -blockquote - border-left: solid 1px darkgray - margin-left: 25px - padding-left: 15px -.quote - font-style: italic -.source - text-align: right - padding-right: 60px - \ No newline at end of file diff --git a/bit-badger-solutions/src/app/applications/application/application.component.ts b/bit-badger-solutions/src/app/applications/application/application.component.ts deleted file mode 100644 index 0d5d488..0000000 --- a/bit-badger-solutions/src/app/applications/application/application.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Component, OnInit, Input } from '@angular/core' -import { ActivatedRoute } from '@angular/router' - -import { ApplicationService } from '../application.service' -import { App } from '../application.types' - -@Component({ - selector: 'app-application', - templateUrl: './application.component.html', - styleUrls: ['./application.component.sass'] -}) -export class ApplicationComponent implements OnInit { - - /** The app we're displaying */ - application: App - - constructor( - private appService: ApplicationService, - private route: ActivatedRoute - ) { } - - ngOnInit() { - const appId = this.route.snapshot.paramMap.get('appId') - this.appService.getApp(appId) - .subscribe(app => this.application = app) - } - - /** The page title based on this app */ - get pageTitle () { - return `${this.application.name} « Solutions` - } - - /** Whether to link to the app's URL */ - get linkToApp () { - return this.application.isActive || this.application.linkInactive - } - - /** Whether to link to an archive URL */ - get linkToArchive () { - return !this.application.isActive && !this.application.linkInactive && (this.application.archiveUrl > '') - } - - /** The link to the screenshot image */ - get imageLink () { - return `/assets/screenshots/${this.application.id}.png` - } - - /** The alt text for the screenshot image */ - get imageAlt () { - return `Screen shot for ${this.application.name}` - } - -} diff --git a/bit-badger-solutions/src/app/applications/applications.module.ts b/bit-badger-solutions/src/app/applications/applications.module.ts index c29000e..0d7b07c 100644 --- a/bit-badger-solutions/src/app/applications/applications.module.ts +++ b/bit-badger-solutions/src/app/applications/applications.module.ts @@ -3,15 +3,54 @@ import { CommonModule } from '@angular/common' import { RouterModule } from '@angular/router' import { SharedModule } from '../shared/shared.module' -import { ApplicationComponent } from './application/application.component'; -import { ApplicationListComponent } from './application-list/application-list.component'; +import { ApplicationComponent } from './application.component' +import { ApplicationListComponent } from './application-list/application-list.component' import { ApplicationListItemComponent } from './application-list-item/application-list-item.component' +import { PrayerTrackerComponent } from './solutions/prayer-tracker.component' +import { ApplicationHeaderComponent } from './application-header/application-header.component' +import { AllSolutionsLinkComponent } from './all-solutions-link.component' +import { ApplicationImageComponent } from './application-image/application-image.component' +import { VirtualPrayerRoomComponent } from './solutions/virtual-prayer-room.component' +import { ApplicationDetailDirective } from './application-detail.directive' +import { BayVistaComponent } from './solutions/bay-vista.component' +import { CassyFianoComponent } from './solutions/cassy-fiano.component' +import { DrMelissaClouthierComponent } from './solutions/dr-melissa-clouthier.component'; +import { EmeraldMountainChristianSchoolComponent } from './solutions/emerald-mountain-christian-school.component'; +import { FutilityClosetComponent } from './solutions/futility-closet.component'; +import { QuotesComponent } from './quotes/quotes.component'; +import { HardCorpsWifeComponent } from './solutions/hard-corps-wife.component'; +import { LibertyPunditsComponent } from './solutions/liberty-pundits.component' @NgModule({ declarations: [ ApplicationComponent, ApplicationListComponent, - ApplicationListItemComponent + ApplicationListItemComponent, + PrayerTrackerComponent, + ApplicationHeaderComponent, + AllSolutionsLinkComponent, + ApplicationImageComponent, + VirtualPrayerRoomComponent, + ApplicationDetailDirective, + BayVistaComponent, + CassyFianoComponent, + DrMelissaClouthierComponent, + EmeraldMountainChristianSchoolComponent, + FutilityClosetComponent, + QuotesComponent, + HardCorpsWifeComponent, + LibertyPunditsComponent + ], + entryComponents: [ + BayVistaComponent, + CassyFianoComponent, + DrMelissaClouthierComponent, + EmeraldMountainChristianSchoolComponent, + FutilityClosetComponent, + HardCorpsWifeComponent, + LibertyPunditsComponent, + PrayerTrackerComponent, + VirtualPrayerRoomComponent ], imports: [ CommonModule, diff --git a/bit-badger-solutions/src/app/applications/quotes/quotes.component.html b/bit-badger-solutions/src/app/applications/quotes/quotes.component.html new file mode 100644 index 0000000..f76a6df --- /dev/null +++ b/bit-badger-solutions/src/app/applications/quotes/quotes.component.html @@ -0,0 +1,10 @@ +
+

What They Say

+
+

+

+ — {{ quote.name }} + , {{ quote.from }} +

+
+
diff --git a/bit-badger-solutions/src/app/applications/quotes/quotes.component.sass b/bit-badger-solutions/src/app/applications/quotes/quotes.component.sass new file mode 100644 index 0000000..5295202 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/quotes/quotes.component.sass @@ -0,0 +1,9 @@ +blockquote + border-left: solid 1px darkgray + margin-left: 25px + padding-left: 15px +.quote + font-style: italic +.source + text-align: right + padding-right: 60px diff --git a/bit-badger-solutions/src/app/applications/quotes/quotes.component.ts b/bit-badger-solutions/src/app/applications/quotes/quotes.component.ts new file mode 100644 index 0000000..a13b7cc --- /dev/null +++ b/bit-badger-solutions/src/app/applications/quotes/quotes.component.ts @@ -0,0 +1,18 @@ +import { Component, OnInit, Input } from '@angular/core' + +import { Quote } from '../application.types' + +@Component({ + selector: 'app-quotes', + templateUrl: './quotes.component.html', + styleUrls: ['./quotes.component.sass'] +}) +export class QuotesComponent implements OnInit { + + @Input() quotes: Quote[] + + constructor() { } + + ngOnInit() { } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/app-detail.component.ts b/bit-badger-solutions/src/app/applications/solutions/app-detail.component.ts new file mode 100644 index 0000000..b7728c1 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/app-detail.component.ts @@ -0,0 +1,14 @@ +import { App } from '../application.types' + +/** An inteface implemented by all app detail components */ +export class AppDetailComponent { + + /** The app to be displayed */ + app: App + + /** The page title based on this app */ + get pageTitle () { + return `${this.app.name} « Solutions` + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/bay-vista.component.html b/bit-badger-solutions/src/app/applications/solutions/bay-vista.component.html new file mode 100644 index 0000000..d8f869e --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/bay-vista.component.html @@ -0,0 +1,51 @@ + + +
+ +
+

+ Bay Vista Baptist Church has served the spiritual needs of Mississippi’s Gulf Coast for decades. They + emphasize serving their community as well; they were a hub for + FEMA during Hurricane Katrina relief and recovery + efforts, and they are a relay point for each year’s + Operation Christmas Child + campaign. As of late 2013, the authors of their current website were no longer around, and no one could get to + the site to update it. We proposed setting up a site based on WordPress, where multiple people could have the + ability to maintain the site, reducing the risk of that happening again. We also mentioned that such a site could + also serve a sermon podcast feed, increasing the reach of their ministry. +

+
+

What We Did (2014)

+

+ We manually downloaded all the publically-accessible parts of their old site, and used that content to create a + WordPress-based site, updating a few outdated items along the way. We also established a podcast feed for their + sermons. A few months after initially setting up the site, we updated the theme to be more mobile-friendly. +

+
+
+

What We Did (2016)

+

+ In the nearly three years since we had set up the site, we were the only ones updating it. We had recently + migrated some older blogs to use a static site generator and were impressed with the performance gains. We + converted their site, to include writing a custom template to support the podcast feed; it is now generated + along with the rest of the site. +

+
+
+

What We Did (2019)

+

+ We open sourced the site's source code, and set up + Azure Pipelines to automatically build and deploy the site on demand, as well as the regular podcast episode + release time. +

+
+
+

What We Still Do

+

+ Bit Badger Solutions hosts this site; we also host the church e-mail accounts, and publish sermons to their + podcast feed weekly. +

+
+ +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/bay-vista.component.ts b/bit-badger-solutions/src/app/applications/solutions/bay-vista.component.ts new file mode 100644 index 0000000..6c17d68 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/bay-vista.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core' + +import { AppDetailComponent } from './app-detail.component' +import { App } from '../application.types' + +@Component({ + selector: 'app-bay-vista', + templateUrl: './bay-vista.component.html' +}) +export class BayVistaComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/cassy-fiano.component.html b/bit-badger-solutions/src/app/applications/solutions/cassy-fiano.component.html new file mode 100644 index 0000000..2f5190c --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/cassy-fiano.component.html @@ -0,0 +1,34 @@ + + +
+ +
+

+ Cassy Fiano (now Cassy Chesser) began blogging back in 2007 on Blogger. She worked hard to network with other + bloggers, and wrote prolifically. As she approached the end of her first year of blogging, she was about to + outgrow Blogger. She asked in a blog post if anyone had experience with Movable Type, the platform used by + another blog to which she contributed. I replied that I did not, but that I had experience with WordPress. +

+
+

What We Did (2008)

+

+ We assisted her with finding a theme, and customized that theme to contain the same sidebar elements as her + current Blogger theme. We modified her old Blogger template to send people to her new blog (using redirection) + after displaying a note that the blog had moved. +

+
+
+

What We Did (2012)

+

+ In July 2012, we began hosting the site, as well as continuing support for theme updates. This joined her + military wife blog Hard Corps Wife, which we had begun hosting in mid-2011. +

+
+
+

What We Still Do

+

Cassy formally decommissioned this site in early 2014.

+
+ +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/cassy-fiano.component.ts b/bit-badger-solutions/src/app/applications/solutions/cassy-fiano.component.ts new file mode 100644 index 0000000..d9a189f --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/cassy-fiano.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core' + +import { AppDetailComponent } from './app-detail.component' +import { App } from '../application.types' + +@Component({ + selector: 'app-cassy-fiano', + templateUrl: './cassy-fiano.component.html' +}) +export class CassyFianoComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/dr-melissa-clouthier.component.html b/bit-badger-solutions/src/app/applications/solutions/dr-melissa-clouthier.component.html new file mode 100644 index 0000000..44e984d --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/dr-melissa-clouthier.component.html @@ -0,0 +1,33 @@ + + +
+ +
+

+ Dr. Melissa Clouthier saw our work with Cassy’s site, and asked us to help her move off Blogger as + well. Melissa blogs from the political right, but also covers health issues and social media. She had been + blogging for a several years, and wanted to bring her old content with her to her new site. +

+
+

What We Did (2009)

+

+ We created a custom theme based on another site, and developed graphics to complement that theme. We also + imported the content from her Blogger site into the WordPress site, and created a featured content template for + the front page. +

+
+
+

What We Did (2018)

+

+ Melissa decommissioned her site; we took final snapshots of the information there, then assisted with shutting + it down. +

+
+

+ (NOTE: The thumbnail of the site represents a new skin on the original theme; while the theme is the + same, Bit Badger Solutions did not create the graphics.) +

+ +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/dr-melissa-clouthier.component.ts b/bit-badger-solutions/src/app/applications/solutions/dr-melissa-clouthier.component.ts new file mode 100644 index 0000000..7bfa9c9 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/dr-melissa-clouthier.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core' + +import { AppDetailComponent } from './app-detail.component' +import { App } from '../application.types' + +@Component({ + selector: 'app-dr-melissa-clouthier', + templateUrl: './dr-melissa-clouthier.component.html' +}) +export class DrMelissaClouthierComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/emerald-mountain-christian-school.component.html b/bit-badger-solutions/src/app/applications/solutions/emerald-mountain-christian-school.component.html new file mode 100644 index 0000000..350aa3e --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/emerald-mountain-christian-school.component.html @@ -0,0 +1,40 @@ + + +
+ +
+

+ Emerald Mountain Christian School is a private Christian school founded over 50 years ago. They use the Principle + Approach®, which emphasizes research, reasoning, relating, and recording to help students synthesize the + information they learn, rather than just requiring rote memorization. More information about the school’s + rich history can be found on their site. +

+
+

What We Did (2004)

+

+ They had a website with very basic information and very little styling. We developed a theme (the one in the + thumbnail), based in large part on the design of their printed materials, and they approved the design. + Initially, the site only contained the content from their previous site. We then put their school calendar of + events up on the site, where parents could find the dates for upcoming events. Finally, we put all the material + from their Parent Information Packet online, which helped prospective families learn more about the school + before visiting it. +

+
+
+

What We Did (2011)

+

+ The underlying engine of the basic website was switched from PHP to an ASP MVC web application, and the + back-end database was switched from MySQL to a PostgreSQL database. +

+
+
+

What We Did (2013)

+

+ We passed off the content and hosting of the site to a new maintainer. They have since redesigned it; it is + accessible via the URL above, and at EMCSpatriots.org. +

+
+ +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/emerald-mountain-christian-school.component.ts b/bit-badger-solutions/src/app/applications/solutions/emerald-mountain-christian-school.component.ts new file mode 100644 index 0000000..98775cf --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/emerald-mountain-christian-school.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core' + +import { AppDetailComponent } from './app-detail.component' +import { App } from '../application.types' + +@Component({ + selector: 'app-emerald-mountain-christian-school', + templateUrl: './emerald-mountain-christian-school.component.html' +}) +export class EmeraldMountainChristianSchoolComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/futility-closet.component.html b/bit-badger-solutions/src/app/applications/solutions/futility-closet.component.html new file mode 100644 index 0000000..6b7af26 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/futility-closet.component.html @@ -0,0 +1,29 @@ + + +
+ +
+

+ Futility Closet exists as a place to give people a break from the dullness of work, by providing puzzles, + anecdotes, and more. It began on a shared host, but was growing too large and popular for that platform. +

+
+

What We Did

+

+ We determined what the traffic requirements and size of the blog were, then made some recommendations. Greg + Ross, the site author, decided on one of our recommendations. He had backups of the existing database, so we + were able to set up a server and restore the data onto that new server. We configured WordPress and locked down + the server, and this blog was moved quickly. +

+
+
+

What We Still Do

+

+ Bit Badger Solutions still hosts Futility Closet, ensuring that the underlying server receives performance and + security upgrades, monitoring site performance, and maintaining regular backups. +

+
+ + +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/futility-closet.component.ts b/bit-badger-solutions/src/app/applications/solutions/futility-closet.component.ts new file mode 100644 index 0000000..10e3edc --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/futility-closet.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core' + +import { AppDetailComponent } from './app-detail.component' +import { App } from '../application.types' + +@Component({ + selector: 'app-futility-closet', + templateUrl: './futility-closet.component.html' +}) +export class FutilityClosetComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/hard-corps-wife.component.html b/bit-badger-solutions/src/app/applications/solutions/hard-corps-wife.component.html new file mode 100644 index 0000000..99023dd --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/hard-corps-wife.component.html @@ -0,0 +1,23 @@ + + +
+ +
+

+ Capitalizing on the growth from her Cassy Fiano blog, Cassy (now Chesser) began a separate blog in which she + could chronicle her experience as a military spouse. +

+
+

What We Did

+

We customized the header and sidebar of the theme, and set up the hardcorpswife.com domain.

+
+
+

What We Still Do

+

+ In 2013, Cassy shifted priorities and closed this site down. She can still be found at other places around the + web. +

+
+ +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/hard-corps-wife.component.ts b/bit-badger-solutions/src/app/applications/solutions/hard-corps-wife.component.ts new file mode 100644 index 0000000..091b830 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/hard-corps-wife.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core' + +import { AppDetailComponent } from './app-detail.component' +import { App } from '../application.types' + +@Component({ + selector: 'app-hard-corps-wife', + templateUrl: './hard-corps-wife.component.html' +}) +export class HardCorpsWifeComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/liberty-pundits.component.html b/bit-badger-solutions/src/app/applications/solutions/liberty-pundits.component.html new file mode 100644 index 0000000..3bd13bd --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/liberty-pundits.component.html @@ -0,0 +1,39 @@ + + +
+ +
+

+ At its founding, Liberty Pundits was a joint venture by 3 established bloggers (Melissa Clouthier, Bill Dupray, + and Clyde Middleton) that, in their words, was aimed at becoming the new home for conservatives on the Internet. + With the three of them all being prolific bloggers in their own right, and the help of many contributors, Liberty + Pundits was a bustling hub of information. +

+
+

What We Did

+

+ Bill and Clyde had been part of Patriot Room, an already-recognized powerhouse, and their desire was for + Liberty Pundits to contain the content that they had contributed to Patriot Room. The technical lead on that + blog had moved on, so we did some divining of what was there. Once we deduced the current setup, we obtained + the data from that site, determined how it would need to be manipulated to become part of a WordPress blog, + then accomplished the data migration. Initially, this was deployed on the same shared hosting account where + LibertyPundits.com, their podcast distribution site, already resided. The site’s traffic quickly + overwhelmed that solution. They then were moved by their host to a + VPS, which performed moderately better, but still had quite a few + issues, mostly related to the site’s traffic volume. We recommended a new server configuration, including + migrating from a fully-featured web server to a more lightweight web server, along with caching, and configured + that server. This configuration eliminated the bottlenecks, and enabled them to have several 100,000+ hit days + with no appreciable slowdowns. +

+
+
+

What We Still Do

+

+ Bit Badger Solutions maintained the server, keeping it current with performance and security upgrades. We also + provided support to the primary 3 bloggers, when they had questions about WordPress or how the site was + performing. The site closed in August of 2011, as the primary authors moved on to other endeavors. +

+
+ +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/liberty-pundits.component.ts b/bit-badger-solutions/src/app/applications/solutions/liberty-pundits.component.ts new file mode 100644 index 0000000..1885051 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/liberty-pundits.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core' + +import { AppDetailComponent } from './app-detail.component' +import { App } from '../application.types' + +@Component({ + selector: 'app-liberty-pundits', + templateUrl: './liberty-pundits.component.html' +}) +export class LibertyPunditsComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/prayer-tracker.component.html b/bit-badger-solutions/src/app/applications/solutions/prayer-tracker.component.html new file mode 100644 index 0000000..be603e1 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/prayer-tracker.component.html @@ -0,0 +1,44 @@ + + +
+ +
+

+ Years ago, Daniel was responsible for keeping up with prayer requests for his Sunday School class. To help him + keep up with requests, automatically drop requests that were old, and track long-term requests, he wrote a custom + app made up of a few pages. Over time, he added security mechanisms and other options, arriving at the site that + exists today. It is provided free for the asking to any church, Sunday School class, or small group that desires + a tool to help them establish a continuous list of prayer requests. +

+
+

What We Did (2005)

+

Created the original site.

+
+
+

What We Did (2011)

+

+ We rewrote this application using a more modern (at the time) framework (ASP MVC 3), building the security + additions from the ground up, and posturing it for an interface with + Virtual + Prayer Room. +

+
+
+

What We Did (2012)

+

In April 2012, version 4 was released with support for Spanish - our first multi-lingual application!

+
+
+

What We Did (2018)

+

Version 7 brought full mobile accessibility, along with an upgrade to a modern, ultra-fast web framework.

+
+
+

What We Did (2019)

+

PrayerTracker became an open source project.

+
+
+

What We Still Do

+

Host and maintain this application.

+
+ +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/prayer-tracker.component.ts b/bit-badger-solutions/src/app/applications/solutions/prayer-tracker.component.ts new file mode 100644 index 0000000..131a83d --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/prayer-tracker.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core' + +import { AppDetailComponent } from './app-detail.component' +import { App } from '../application.types' + +@Component({ + selector: 'app-prayer-tracker', + templateUrl: './prayer-tracker.component.html' +}) +export class PrayerTrackerComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/app/applications/solutions/virtual-prayer-room.component.html b/bit-badger-solutions/src/app/applications/solutions/virtual-prayer-room.component.html new file mode 100644 index 0000000..a9a5475 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/virtual-prayer-room.component.html @@ -0,0 +1,32 @@ + + +
+ +
+

+ Many churches have prayer rooms – rooms set aside for people to come in to pray. Hoffmantown Church in + Albuquerque, New Mexico was one of these churches. However, they had seen the use of this physical prayer room + dwindling over the years. People had become less willing to drive to the church, especially at night, and + security became an issue as well; either prayer warriors had to know how to disable the security system, or the + church would have to remain unlocked. +

+

+ Having seen our work with the Not So Extreme Makeover: Community + Edition, the church contacted us to see if something similar could be developed to help their prayer + ministry. The resulting application that was developed extended the prayer room to wherever the prayer warrior + can get an Internet connection! Prayer warriors could enlist right from the site, and had to be approved. + Requests and updates were tracked by date/time, and warriors could record when they’ve prayed for a request + from the site, or from clicking a link in the daily e-mail they received with requests from their interest areas. + As many prayer needs are confidential, security and confidentiality were very important. Virtual Prayer Room + ensured these by providing varying security levels for prayer warriors and the ability to mark each request as + confidential. +

+

+ In 2016, Hoffmantown Church elected to begin using another package for their prayer requests. While a few other + churches had expressed interest in it, none ultimately decided to use it; so, in 2017, Virtual Prayer Room was + officially decommissioned. +

+ +
+
diff --git a/bit-badger-solutions/src/app/applications/solutions/virtual-prayer-room.component.ts b/bit-badger-solutions/src/app/applications/solutions/virtual-prayer-room.component.ts new file mode 100644 index 0000000..7c59bf8 --- /dev/null +++ b/bit-badger-solutions/src/app/applications/solutions/virtual-prayer-room.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; + +import { AppDetailComponent } from './app-detail.component'; +import { App } from '../application.types'; + +@Component({ + selector: 'app-virtual-prayer-room', + templateUrl: './virtual-prayer-room.component.html' +}) +export class VirtualPrayerRoomComponent extends AppDetailComponent { + + @Input() app: App + + constructor() { + super() + } + +} diff --git a/bit-badger-solutions/src/styles.sass b/bit-badger-solutions/src/styles.sass index c6a0c1b..7733d36 100644 --- a/bit-badger-solutions/src/styles.sass +++ b/bit-badger-solutions/src/styles.sass @@ -52,3 +52,7 @@ ul padding-left: 40px li list-style-type: disc +.app-info + display: flex + flex-flow: row-reverse wrap + justify-content: center