Compare commits
10 Commits
255769e005
...
b614c2fdd8
Author | SHA1 | Date | |
---|---|---|---|
b614c2fdd8 | |||
b9bf19d710 | |||
c7fb7cfc20 | |||
0aaf06b050 | |||
dcf28915f7 | |||
128c554ce5 | |||
9e80e528c9 | |||
e1487e9009 | |||
f27d995a98 | |||
|
36281389dc |
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,3 +15,6 @@ selenium-debug.log
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
.ionide/
|
.ionide/
|
||||||
|
|
||||||
|
# Zipped theme
|
||||||
|
**/*.zip
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
# Bit Badger Solutions
|
# Bit Badger Solutions
|
||||||
|
|
||||||
[![Build status](https://danieljsummers.visualstudio.com/Bit%20Badger%20Solutions/_apis/build/status/Bit%20Badger%20Solutions-CI)](https://danieljsummers.visualstudio.com/Bit%20Badger%20Solutions/_build/latest?definitionId=2)
|
This repository contains the [myWebLog](https://bitbadger.solutions/open-source/myweblog/) theme for the [Bit Badger Solutions](https://bitbadger.solutions) website
|
||||||
|
|
||||||
This is the source repository for the [Bit Badger Solutions](https://bitbadger.solutions) website
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
# 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
|
|
46
bit-badger-solutions/.gitignore
vendored
46
bit-badger-solutions/.gitignore
vendored
@ -1,46 +0,0 @@
|
|||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# compiled output
|
|
||||||
/dist
|
|
||||||
/tmp
|
|
||||||
/out-tsc
|
|
||||||
# Only exists if Bazel was run
|
|
||||||
/bazel-out
|
|
||||||
|
|
||||||
# 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
|
|
@ -1,128 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
||||||
"version": 1,
|
|
||||||
"newProjectRoot": "projects",
|
|
||||||
"projects": {
|
|
||||||
"bit-badger-solutions": {
|
|
||||||
"projectType": "application",
|
|
||||||
"schematics": {
|
|
||||||
"@schematics/angular:component": {
|
|
||||||
"style": "sass"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "",
|
|
||||||
"sourceRoot": "src",
|
|
||||||
"prefix": "app",
|
|
||||||
"architect": {
|
|
||||||
"build": {
|
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
|
||||||
"options": {
|
|
||||||
"outputPath": "dist/bit-badger-solutions",
|
|
||||||
"index": "src/index.html",
|
|
||||||
"main": "src/main.ts",
|
|
||||||
"polyfills": "src/polyfills.ts",
|
|
||||||
"tsConfig": "tsconfig.app.json",
|
|
||||||
"aot": true,
|
|
||||||
"assets": [
|
|
||||||
"src/favicon.ico",
|
|
||||||
"src/assets"
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"src/styles.sass"
|
|
||||||
],
|
|
||||||
"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,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"vendorChunk": false,
|
|
||||||
"buildOptimizer": true,
|
|
||||||
"budgets": [
|
|
||||||
{
|
|
||||||
"type": "initial",
|
|
||||||
"maximumWarning": "2mb",
|
|
||||||
"maximumError": "5mb"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "anyComponentStyle",
|
|
||||||
"maximumWarning": "6kb",
|
|
||||||
"maximumError": "10kb"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"serve": {
|
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
|
||||||
"options": {
|
|
||||||
"browserTarget": "bit-badger-solutions:build"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"browserTarget": "bit-badger-solutions:build:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extract-i18n": {
|
|
||||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
|
||||||
"options": {
|
|
||||||
"browserTarget": "bit-badger-solutions:build"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
|
||||||
"options": {
|
|
||||||
"main": "src/test.ts",
|
|
||||||
"polyfills": "src/polyfills.ts",
|
|
||||||
"tsConfig": "tsconfig.spec.json",
|
|
||||||
"karmaConfig": "karma.conf.js",
|
|
||||||
"assets": [
|
|
||||||
"src/favicon.ico",
|
|
||||||
"src/assets"
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"src/styles.sass"
|
|
||||||
],
|
|
||||||
"scripts": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": [
|
|
||||||
"tsconfig.app.json",
|
|
||||||
"tsconfig.spec.json",
|
|
||||||
"e2e/tsconfig.json"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"e2e": {
|
|
||||||
"builder": "@angular-devkit/build-angular:protractor",
|
|
||||||
"options": {
|
|
||||||
"protractorConfig": "e2e/protractor.conf.js",
|
|
||||||
"devServerTarget": "bit-badger-solutions:serve"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"devServerTarget": "bit-badger-solutions:serve:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
"defaultProject": "bit-badger-solutions"
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
|
||||||
# For additional information regarding the format and rule options, please see:
|
|
||||||
# https://github.com/browserslist/browserslist#queries
|
|
||||||
|
|
||||||
# You can see what browsers were selected by your queries by running:
|
|
||||||
# npx browserslist
|
|
||||||
|
|
||||||
> 0.5%
|
|
||||||
last 2 versions
|
|
||||||
Firefox ESR
|
|
||||||
not dead
|
|
||||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
|
@ -1,32 +0,0 @@
|
|||||||
// @ts-check
|
|
||||||
// Protractor configuration file, see link for more information
|
|
||||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
|
||||||
|
|
||||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type { import("protractor").Config }
|
|
||||||
*/
|
|
||||||
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.json')
|
|
||||||
});
|
|
||||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
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('bit-badger-solutions app is running!');
|
|
||||||
});
|
|
||||||
|
|
||||||
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,
|
|
||||||
} as logging.Entry));
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,11 +0,0 @@
|
|||||||
import { browser, by, element } from 'protractor';
|
|
||||||
|
|
||||||
export class AppPage {
|
|
||||||
navigateTo() {
|
|
||||||
return browser.get(browser.baseUrl) as Promise<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTitleText() {
|
|
||||||
return element(by.css('app-root .content span')).getText() as Promise<string>;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/e2e",
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es5",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"jasminewd2",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
// 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/bit-badger-solutions'),
|
|
||||||
reports: ['html', 'lcovonly', 'text-summary'],
|
|
||||||
fixWebpackSourcePaths: true
|
|
||||||
},
|
|
||||||
reporters: ['progress', 'kjhtml'],
|
|
||||||
port: 9876,
|
|
||||||
colors: true,
|
|
||||||
logLevel: config.LOG_INFO,
|
|
||||||
autoWatch: true,
|
|
||||||
browsers: ['Chrome'],
|
|
||||||
singleRun: false,
|
|
||||||
restartOnFileChange: true
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "bit-badger-solutions",
|
|
||||||
"version": "3.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": "~9.1.0",
|
|
||||||
"@angular/common": "~9.1.0",
|
|
||||||
"@angular/compiler": "~9.1.0",
|
|
||||||
"@angular/core": "~9.1.0",
|
|
||||||
"@angular/forms": "~9.1.0",
|
|
||||||
"@angular/platform-browser": "~9.1.0",
|
|
||||||
"@angular/platform-browser-dynamic": "~9.1.0",
|
|
||||||
"@angular/router": "~9.1.0",
|
|
||||||
"rxjs": "~6.5.5",
|
|
||||||
"tslib": "^1.10.0",
|
|
||||||
"zone.js": "~0.10.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@angular-devkit/build-angular": "~0.901.0",
|
|
||||||
"@angular/cli": "~9.1.0",
|
|
||||||
"@angular/compiler-cli": "~9.1.0",
|
|
||||||
"@angular/language-service": "~9.1.0",
|
|
||||||
"@types/jasmine": "~3.3.8",
|
|
||||||
"@types/jasminewd2": "~2.0.3",
|
|
||||||
"@types/node": "^12.11.1",
|
|
||||||
"codelyzer": "^5.1.2",
|
|
||||||
"jasmine-core": "~3.4.0",
|
|
||||||
"jasmine-spec-reporter": "~4.2.1",
|
|
||||||
"karma": "~4.1.0",
|
|
||||||
"karma-chrome-launcher": "~2.2.0",
|
|
||||||
"karma-coverage-istanbul-reporter": "~2.0.1",
|
|
||||||
"karma-jasmine": "~2.0.1",
|
|
||||||
"karma-jasmine-html-reporter": "^1.4.0",
|
|
||||||
"protractor": "~5.4.0",
|
|
||||||
"ts-node": "~7.0.0",
|
|
||||||
"tslint": "~5.15.0",
|
|
||||||
"typescript": "~3.8.3"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core'
|
|
||||||
import { Routes, RouterModule } from '@angular/router'
|
|
||||||
|
|
||||||
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'
|
|
||||||
import { LegacyDataComponent } from './pages/about/legacy-data.component'
|
|
||||||
import { ProcessAutomationComponent } from './pages/about/process-automation.component'
|
|
||||||
import { WebServicesComponent } from './pages/about/web-services.component'
|
|
||||||
import { WhyBitBadgerComponent } from './pages/about/why-bit-badger.component'
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{ path: '', component: HomeComponent },
|
|
||||||
{ path: 'about/information-publicizing-solutions', component: InformationPublicizingComponent },
|
|
||||||
{ path: 'about/legacy-data', component: LegacyDataComponent },
|
|
||||||
{ path: 'about/process-automation-solutions', component: ProcessAutomationComponent },
|
|
||||||
{ path: 'about/web-services-solutions', component: WebServicesComponent },
|
|
||||||
{ path: 'about/why-bit-badger', component: WhyBitBadgerComponent },
|
|
||||||
{ path: 'solutions', component: ApplicationListComponent },
|
|
||||||
{ path: 'solutions/:appId', component: ApplicationComponent }
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
|
|
||||||
exports: [RouterModule]
|
|
||||||
})
|
|
||||||
export class AppRoutingModule { }
|
|
@ -1,5 +0,0 @@
|
|||||||
<app-header></app-header>
|
|
||||||
<div id="content">
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
</div>
|
|
||||||
<app-footer></app-footer>
|
|
@ -1,35 +0,0 @@
|
|||||||
import { TestBed, async } from '@angular/core/testing';
|
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
|
|
||||||
describe('AppComponent', () => {
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
RouterTestingModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
AppComponent
|
|
||||||
],
|
|
||||||
}).compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should create the app', () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.debugElement.componentInstance;
|
|
||||||
expect(app).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should have as title 'bit-badger-solutions'`, () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.debugElement.componentInstance;
|
|
||||||
expect(app.title).toEqual('bit-badger-solutions');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render title', () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
fixture.detectChanges();
|
|
||||||
const compiled = fixture.debugElement.nativeElement;
|
|
||||||
expect(compiled.querySelector('.content span').textContent).toContain('bit-badger-solutions app is running!');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,10 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
templateUrl: './app.component.html',
|
|
||||||
styleUrls: ['./app.component.sass']
|
|
||||||
})
|
|
||||||
export class AppComponent {
|
|
||||||
title = 'bit-badger-solutions';
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core'
|
|
||||||
import { BrowserModule } from '@angular/platform-browser'
|
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module'
|
|
||||||
import { ApplicationsModule } from './applications/applications.module'
|
|
||||||
import { SharedModule } from './shared/shared.module'
|
|
||||||
import { SidebarModule } from './sidebar/sidebar.module'
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component'
|
|
||||||
import { HomeComponent } from './pages/home/home.component'
|
|
||||||
import { WhyBitBadgerComponent } from './pages/about/why-bit-badger.component'
|
|
||||||
import { InformationPublicizingComponent } from './pages/about/information-publicizing.component'
|
|
||||||
import { LegacyDataComponent } from './pages/about/legacy-data.component'
|
|
||||||
import { ProcessAutomationComponent } from './pages/about/process-automation.component'
|
|
||||||
import { WebServicesComponent } from './pages/about/web-services.component'
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
AppComponent,
|
|
||||||
HomeComponent,
|
|
||||||
WhyBitBadgerComponent,
|
|
||||||
InformationPublicizingComponent,
|
|
||||||
LegacyDataComponent,
|
|
||||||
ProcessAutomationComponent,
|
|
||||||
WebServicesComponent,
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
BrowserAnimationsModule,
|
|
||||||
AppRoutingModule,
|
|
||||||
ApplicationsModule,
|
|
||||||
SharedModule,
|
|
||||||
SidebarModule
|
|
||||||
],
|
|
||||||
providers: [],
|
|
||||||
bootstrap: [AppComponent]
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-all-solutions-link',
|
|
||||||
template: `<p><br><a routerLink="/solutions">« Back to All Solutions</a></p>`
|
|
||||||
})
|
|
||||||
export class AllSolutionsLinkComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import { Type } from '@angular/core'
|
|
||||||
|
|
||||||
/** An item representing an app */
|
|
||||||
export class AppItem {
|
|
||||||
constructor(public name: string, public component: Type<any>) { }
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
import { Directive, ViewContainerRef } from '@angular/core'
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[app-application-detail]'
|
|
||||||
})
|
|
||||||
export class ApplicationDetailDirective {
|
|
||||||
|
|
||||||
constructor(public viewContainerRef: ViewContainerRef) { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
<h1>
|
|
||||||
{{ app.name }}<br>
|
|
||||||
<small><small>
|
|
||||||
<a *ngIf="linkToApp" [href]="app.url">{{ app.url }}</a>
|
|
||||||
<span *ngIf="!linkToApp">{{ app.url }}</span>
|
|
||||||
<span *ngIf="linkToArchive">
|
|
||||||
<a [href]="app.archiveUrl"><small>(Archive)</small></a>
|
|
||||||
</span>
|
|
||||||
</small></small>
|
|
||||||
</h1>
|
|
@ -1,2 +0,0 @@
|
|||||||
h1
|
|
||||||
line-height: 1.6rem
|
|
@ -1,28 +0,0 @@
|
|||||||
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 > '')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
<aside><span> </span><img [src]="imageLink" [alt]="imageAlt"></aside>
|
|
@ -1,9 +0,0 @@
|
|||||||
aside
|
|
||||||
float: right
|
|
||||||
background-color: #FFFAFA
|
|
||||||
aside > span
|
|
||||||
padding-left: .75rem
|
|
||||||
aside > img
|
|
||||||
overflow: hidden
|
|
||||||
border: dotted 1px darkgray
|
|
||||||
border-radius: 10px
|
|
@ -1,29 +0,0 @@
|
|||||||
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}`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
<p>
|
|
||||||
<span class="app-name" [innerHtml]="app.name"></span> ~ <a routerLink="/solutions/{{ app.id }}">About</a>
|
|
||||||
<span *ngIf="app.isActive"> ~ <a [href]="app.url">Visit</a></span>
|
|
||||||
<span *ngIf="!app.isActive && app.archiveUrl">
|
|
||||||
~ <a [href]="app.archiveUrl">Visit</a><em> (archive)</em>
|
|
||||||
</span>
|
|
||||||
<br>
|
|
||||||
<span [innerHtml]="app.indexText"></span>
|
|
||||||
</p>
|
|
@ -1,5 +0,0 @@
|
|||||||
.app-name
|
|
||||||
font-family: "Oswald", "Segoe UI", Ubuntu, "DejaVu Sans", "Liberation Sans", Arial, sans-serif
|
|
||||||
font-size: 1.3rem
|
|
||||||
font-weight: bold
|
|
||||||
color: maroon
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-application-list-item',
|
|
||||||
templateUrl: './application-list-item.component.html',
|
|
||||||
styleUrls: ['./application-list-item.component.sass']
|
|
||||||
})
|
|
||||||
export class ApplicationListItemComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
<app-page-title title="All Solutions"></app-page-title>
|
|
||||||
<article class="content auto">
|
|
||||||
<h1>All Solutions</h1>
|
|
||||||
<h2>Active Solutions</h2>
|
|
||||||
<app-application-list-item *ngFor="let app of current" [app]="app"></app-application-list-item>
|
|
||||||
<h2>Past Solutions</h2>
|
|
||||||
<app-application-list-item *ngFor="let app of past" [app]="app"></app-application-list-item>
|
|
||||||
</article>
|
|
@ -1,25 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
|
|
||||||
import { ApplicationService } from '../application.service'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-application-list',
|
|
||||||
templateUrl: './application-list.component.html'
|
|
||||||
})
|
|
||||||
export class ApplicationListComponent implements OnInit {
|
|
||||||
|
|
||||||
current: App[]
|
|
||||||
|
|
||||||
past: App[]
|
|
||||||
|
|
||||||
constructor(private appService: ApplicationService) { }
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.appService.getApps().subscribe(apps => {
|
|
||||||
this.current = apps.filter(app => app.isActive && !app.noAboutLink)
|
|
||||||
this.past = apps.filter(app => !app.isActive && !app.noAboutLink)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
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 { BayVistaComponent } from './solutions/bay-vista.component'
|
|
||||||
import { BitBadgerBlogComponent } from './solutions/bit-badger-blog.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'
|
|
||||||
import { MindyMackenzieComponent } from './solutions/mindy-mackenzie.component'
|
|
||||||
import { MyPrayerJournalComponent } from './solutions/my-prayer-journal.component'
|
|
||||||
import { NsxComponent } from './solutions/nsx.component'
|
|
||||||
import { OlivetBaptistComponent } from './solutions/olivet-baptist.component'
|
|
||||||
import { PhotographyByMichelleComponent } from './solutions/photography-by-michelle.component'
|
|
||||||
import { PrayerTrackerComponent } from './solutions/prayer-tracker.component'
|
|
||||||
import { RiehlWorldNewsComponent } from './solutions/riehl-world-news.component'
|
|
||||||
import { SharkTankComponent } from './solutions/shark-tank.component'
|
|
||||||
import { TcmsComponent } from './solutions/tcms.component'
|
|
||||||
import { VirtualPrayerRoomComponent } from './solutions/virtual-prayer-room.component'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-application',
|
|
||||||
template: '<ng-template app-application-detail></ng-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('mindy-mackenzie', MindyMackenzieComponent),
|
|
||||||
new AppItem('my-prayer-journal', MyPrayerJournalComponent),
|
|
||||||
new AppItem('nsx', NsxComponent),
|
|
||||||
new AppItem('olivet-baptist', OlivetBaptistComponent),
|
|
||||||
new AppItem('photography-by-michelle', PhotographyByMichelleComponent),
|
|
||||||
new AppItem('prayer-tracker', PrayerTrackerComponent),
|
|
||||||
new AppItem('riehl-world-news', RiehlWorldNewsComponent),
|
|
||||||
new AppItem('the-shark-tank', SharkTankComponent),
|
|
||||||
new AppItem('tcms', TcmsComponent),
|
|
||||||
new AppItem('tech-blog', BitBadgerBlogComponent),
|
|
||||||
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 => {
|
|
||||||
(<AppDetailComponent>componentRef.instance).app = app
|
|
||||||
this.application = app
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,323 +0,0 @@
|
|||||||
import { App, Category, Quote, Technology } from './application.types'
|
|
||||||
|
|
||||||
/** A Word from the Word */
|
|
||||||
const aWordFromTheWord = new App('a-word-from-the-word', 'A Word from the Word', 'https://devotions.summershome.org')
|
|
||||||
aWordFromTheWord.categoryId = Category.PERSONAL
|
|
||||||
aWordFromTheWord.noAboutLink = true
|
|
||||||
aWordFromTheWord.frontPageText = 'Devotions by Daniel'
|
|
||||||
aWordFromTheWord.frontPageOrder = 2
|
|
||||||
|
|
||||||
/** Bay Vista Baptist Church */
|
|
||||||
const bayVista = new App('bay-vista', 'Bay Vista Baptist Church', 'https://bayvista.org')
|
|
||||||
bayVista.categoryId = Category.STATIC
|
|
||||||
bayVista.frontPageText = 'Biloxi, Mississippi'
|
|
||||||
bayVista.frontPageOrder = 1
|
|
||||||
bayVista.indexText = 'Southern Baptist church in Biloxi, Mississippi'
|
|
||||||
bayVista.techStack = [
|
|
||||||
new Technology('Hugo', 'static site generation', true),
|
|
||||||
new Technology('Azure', 'podcast file storage, automated builds, and static site hosting', true),
|
|
||||||
new Technology('GitHub', 'source code control', true),
|
|
||||||
new Technology('Hexo', 'static site generation'),
|
|
||||||
new Technology('Jekyll', 'static site generation'),
|
|
||||||
new Technology('WordPress', 'content management'),
|
|
||||||
new Technology('MySQL', 'data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** The Bit Badger Blog */
|
|
||||||
const techBlog = new App('tech-blog', 'The Bit Badger Blog', 'https://blog.bitbadger.solutions')
|
|
||||||
techBlog.categoryId = Category.STATIC
|
|
||||||
techBlog.frontPageText = 'Technical information (“geek stuff”) from Bit Badger Solutions'
|
|
||||||
techBlog.frontPageOrder = 3
|
|
||||||
techBlog.indexText = 'Geek stuff from Bit Badger Solutions'
|
|
||||||
techBlog.techStack = [
|
|
||||||
new Technology('Hexo', 'static site generation', true),
|
|
||||||
new Technology('Azure', 'static site hosting', true),
|
|
||||||
new Technology('GitHub', 'source code control', true),
|
|
||||||
new Technology('Custom software', 'content management'),
|
|
||||||
new Technology('WordPress', 'content management'),
|
|
||||||
new Technology('BlogEngine.NET', 'content management'),
|
|
||||||
new Technology('Orchard', 'content management'),
|
|
||||||
new Technology('myWebLog', 'content management'),
|
|
||||||
new Technology('Jekyll', 'static site generation'),
|
|
||||||
new Technology('MySQL', 'data storage'),
|
|
||||||
new Technology('SQL Server', 'data storage'),
|
|
||||||
new Technology('RethinkDB', 'data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Cassy Fiano */
|
|
||||||
const cassyFiano = new App('cassy-fiano', 'Cassy Fiano', 'http://www.cassyfiano.com')
|
|
||||||
cassyFiano.isActive = false
|
|
||||||
cassyFiano.categoryId = Category.WORDPRESS
|
|
||||||
cassyFiano.indexText = 'A “rising star” conservative blogger'
|
|
||||||
cassyFiano.techStack = [
|
|
||||||
new Technology('WordPress', 'blogging (with a custom theme)'),
|
|
||||||
new Technology('MySQL', 'data storage'),
|
|
||||||
new Technology('Rackspace Cloud', 'backup and recovery'),
|
|
||||||
new Technology('Azure', 'backup and recovery')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Daniel J. Summers */
|
|
||||||
const danielJSummers = new App('daniel-j-summers', 'Daniel J. Summers', 'https://daniel.summershome.org')
|
|
||||||
danielJSummers.categoryId = Category.PERSONAL
|
|
||||||
danielJSummers.noAboutLink = true
|
|
||||||
danielJSummers.frontPageText = 'Daniel’s personal blog',
|
|
||||||
danielJSummers.frontPageOrder = 1
|
|
||||||
|
|
||||||
/** Dr. Melissa Clouthier */
|
|
||||||
const drMelissaClouthier = new App('dr-melissa-clouthier', 'Dr. Melissa Clouthier', 'http://melissablogs.com')
|
|
||||||
drMelissaClouthier.isActive = false
|
|
||||||
drMelissaClouthier.categoryId = Category.WORDPRESS
|
|
||||||
drMelissaClouthier.frontPageText = 'Information Pollination'
|
|
||||||
drMelissaClouthier.frontPageOrder = 1
|
|
||||||
drMelissaClouthier.indexText = 'Politics, health, podcasts and more'
|
|
||||||
drMelissaClouthier.techStack = [
|
|
||||||
new Technology('WordPress', 'blogging (with a custom theme)'),
|
|
||||||
new Technology('MySQL', 'data storage'),
|
|
||||||
new Technology('Rackspace Cloud', 'backup and recovery'),
|
|
||||||
new Technology('Azure', 'backup and recovery')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Emerald Mountain Christian School */
|
|
||||||
const emcs = new App('emerald-mountain-christian-school', 'Emerald Mountain Christian School',
|
|
||||||
'http://www.emeraldmountainchristianschool.org')
|
|
||||||
emcs.isActive = false
|
|
||||||
emcs.linkInactive = true
|
|
||||||
emcs.indexText = 'Classical, Christ-centered education near Wetumpka, Alabama'
|
|
||||||
emcs.techStack = [
|
|
||||||
new Technology('PHP', 'page generation and interactivity'),
|
|
||||||
new Technology('ASP.NET MVC', 'page generation and interactivity'),
|
|
||||||
new Technology('PostgreSQL', 'data storage'),
|
|
||||||
new Technology('Rackspace Cloud', 'hosting'),
|
|
||||||
new Technology('Azure', 'hosting')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Futility Closet */
|
|
||||||
const futilityCloset = new App('futility-closet', 'Futility Closet', 'https://www.futilitycloset.com')
|
|
||||||
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'
|
|
||||||
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
|
|
||||||
setting up and maintaining the site on a Rackspace VPS, and then hosting it completely. Daniel’s never failed
|
|
||||||
in being friendly, knowledgeable, thoughtful, and farsighted. I’ve literally lost count of the number of times
|
|
||||||
he’s saved us from one emergency or another, always with diligence and good humor, or recommended an
|
|
||||||
improvement or a protection that saved us later. We would be out of business many times over if it weren’t for
|
|
||||||
his reliability, expertise, and good judgment. And he’s a joy to work with.`
|
|
||||||
fcQuote.pull = [
|
|
||||||
`Daniel’s never failed in being friendly, knowledgeable, thoughtful, and farsighted…`,
|
|
||||||
`We would be out of business many times over if it weren’t for his reliability, expertise, and good
|
|
||||||
judgment…`
|
|
||||||
]
|
|
||||||
futilityCloset.quotes.push(fcQuote)
|
|
||||||
futilityCloset.techStack = [
|
|
||||||
new Technology('WordPress', 'blogging', true),
|
|
||||||
new Technology('nginx', 'the web server', true),
|
|
||||||
new Technology('MySQL', 'data storage', true),
|
|
||||||
new Technology('Digital Ocean', 'web site hosting', true),
|
|
||||||
new Technology('Azure', 'backup and recovery', true),
|
|
||||||
new Technology('Rackspace Cloud', 'web site hosting')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Hard Corps Wife */
|
|
||||||
const hardCorpsWife = new App('hard-corps-wife', 'Hard Corps Wife', 'http://www.hardcorpswife.com')
|
|
||||||
hardCorpsWife.isActive = false
|
|
||||||
hardCorpsWife.categoryId = Category.WORDPRESS
|
|
||||||
hardCorpsWife.indexText = 'Cassy’s life as a Marine wife'
|
|
||||||
hardCorpsWife.techStack = [
|
|
||||||
new Technology('WordPress', 'blogging'),
|
|
||||||
new Technology('MySQL', 'data storage'),
|
|
||||||
new Technology('Rackspace Cloud', 'web site hosting')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Liberty Pundits */
|
|
||||||
const libertyPundits = new App('liberty-pundits', 'Liberty Pundits', 'http://libertypundits.net')
|
|
||||||
libertyPundits.isActive = false
|
|
||||||
libertyPundits.categoryId = Category.WORDPRESS
|
|
||||||
libertyPundits.indexText = 'The home for conservatives'
|
|
||||||
libertyPundits.techStack = [
|
|
||||||
new Technology('WordPress', 'blogging'),
|
|
||||||
new Technology('PHP', 'custom data migration software'),
|
|
||||||
new Technology('MySQL', 'data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Linux Resources */
|
|
||||||
const linuxResources = new App('linux', 'Linux Resources', 'https://blog.bitbadger.solutions/linux/')
|
|
||||||
linuxResources.noAboutLink = true
|
|
||||||
linuxResources.frontPageText = 'Handy information for Linux folks'
|
|
||||||
linuxResources.frontPageOrder = 3
|
|
||||||
|
|
||||||
/** Mindy Mackenzie */
|
|
||||||
const mindyMackenzie = new App('mindy-mackenzie', 'Mindy Mackenzie', 'https://mindymackenzie.com')
|
|
||||||
mindyMackenzie.categoryId = Category.WORDPRESS
|
|
||||||
mindyMackenzie.frontPageText = 'WSJ-best-selling author of The Courage Solution'
|
|
||||||
mindyMackenzie.frontPageOrder = 3
|
|
||||||
mindyMackenzie.indexText = '<em>Wall Street Journal</em> best-selling author and C-suite advisor'
|
|
||||||
const mmQuote = new Quote('Mindy Mackenzie', '')
|
|
||||||
mmQuote.full =
|
|
||||||
`Daniel is the best partner you could hope for in a web designer and for handling web maintenance! He is smart,
|
|
||||||
creative, resourceful and fast. Daniel is able to produce high quality work on short time frames and with minimal
|
|
||||||
creative direction and hit the mark over and over. The best part, is Daniel is a joy to work with. He is smart,
|
|
||||||
customer-centric and trustworthy. If he says he will get it done, he does. After having a poor experience with
|
|
||||||
another firm, I can highly recommend Daniel for all your website design and support needs – he’s terrific!`
|
|
||||||
mmQuote.pull = [
|
|
||||||
'…Daniel is able to produce high quality work on short time frames…',
|
|
||||||
'[Daniel] is smart, customer-centric and trustworthy.'
|
|
||||||
]
|
|
||||||
mindyMackenzie.quotes.push(mmQuote)
|
|
||||||
mindyMackenzie.techStack = [
|
|
||||||
new Technology('WordPress', 'blogging', true),
|
|
||||||
new Technology('nginx', 'the web server', true),
|
|
||||||
new Technology('MySQL', 'data storage', true),
|
|
||||||
new Technology('Digital Ocean', 'web site hosting', true),
|
|
||||||
new Technology('Azure', 'backup and recovery', true),
|
|
||||||
]
|
|
||||||
|
|
||||||
/** myPrayerJournal */
|
|
||||||
const myPrayerJournal = new App('my-prayer-journal', 'myPrayerJournal', 'https://prayerjournal.me')
|
|
||||||
myPrayerJournal.frontPageText = 'Minimalist personal prayer journal'
|
|
||||||
myPrayerJournal.frontPageOrder = 2
|
|
||||||
myPrayerJournal.indexText = 'Minimalist personal prayer journal'
|
|
||||||
myPrayerJournal.techStack = [
|
|
||||||
new Technology('Vue.js', 'the front-end', true),
|
|
||||||
new Technology('Giraffe', 'the back-end data API', true),
|
|
||||||
new Technology('RavenDB', 'data storage', true),
|
|
||||||
new Technology('GitHub', 'source code control', true),
|
|
||||||
new Technology('GitHub Pages', 'documentation', true),
|
|
||||||
new Technology('PostgreSQL', 'data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Not So Extreme Makeover: Community Edition */
|
|
||||||
const nsx = new App('nsx', 'Not So Extreme Makeover: Community Edition', 'http://notsoextreme.org')
|
|
||||||
nsx.isActive = false
|
|
||||||
nsx.archiveUrl = 'https://nsx.archive.bitbadger.solutions'
|
|
||||||
nsx.indexText =
|
|
||||||
'Public site for the makeover; provides event-driven management of volunteers, donations, and families needing help'
|
|
||||||
nsx.techStack = [
|
|
||||||
new Technology('WordPress', 'content management'),
|
|
||||||
new Technology('PHP', 'NSXapp'),
|
|
||||||
new Technology('MySQL', 'WordPress data storage'),
|
|
||||||
new Technology('PostgreSQL', 'NSXapp data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Olivet Baptist Church */
|
|
||||||
const olivet = new App('olivet-baptist', 'Olivet Baptist Church', 'https://olivet-baptist.org')
|
|
||||||
olivet.isActive = false
|
|
||||||
olivet.archiveUrl = 'https://olivet.archive.bitbadger.solutions'
|
|
||||||
olivet.categoryId = Category.STATIC
|
|
||||||
olivet.indexText = 'Southern Baptist church in Gulfport, Mississippi'
|
|
||||||
olivet.techStack = [
|
|
||||||
new Technology('Vue.js', 'the user interface for the PWA'),
|
|
||||||
new Technology('Hexo', `generating the site's pages`),
|
|
||||||
new Technology('Azure', 'podcast file storage and archive site hosting'),
|
|
||||||
new Technology('WordPress', 'content management'),
|
|
||||||
new Technology('MySQL', 'data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Photography by Michelle */
|
|
||||||
const photographyByMichelle = new App('photography-by-michelle', 'Photography by Michelle',
|
|
||||||
'https://www.summershome.org')
|
|
||||||
photographyByMichelle.isActive = false
|
|
||||||
photographyByMichelle.linkInactive = true
|
|
||||||
photographyByMichelle.indexText = 'Photography services in Albuquerque, New Mexico'
|
|
||||||
photographyByMichelle.techStack = [
|
|
||||||
new Technology('ASP.NET MVC', 'content management / gallery creation API'),
|
|
||||||
new Technology('PostgreSQL', 'data storage'),
|
|
||||||
new Technology('C# / Windows Forms', 'desktop gallery application'),
|
|
||||||
new Technology('WordPress', 'content management'),
|
|
||||||
new Technology('MySQL', 'data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** PrayerTracker */
|
|
||||||
const prayerTracker = new App('prayer-tracker', 'PrayerTracker', 'https://prayer.bitbadger.solutions')
|
|
||||||
prayerTracker.frontPageText = 'A prayer request tracking website (Free for any church or Sunday School class!)'
|
|
||||||
prayerTracker.frontPageOrder = 1
|
|
||||||
prayerTracker.indexText = 'Provides an ongoing, centralized prayer list for Sunday School classes and other groups'
|
|
||||||
prayerTracker.techStack = [
|
|
||||||
new Technology('Giraffe', 'server-side logic and dynamic page generation', true),
|
|
||||||
new Technology('PostgreSQL', 'data storage', true),
|
|
||||||
new Technology('GitHub', 'source code control', true),
|
|
||||||
new Technology('GitHub Pages', 'documentation hosting', true),
|
|
||||||
new Technology('MongoDB', 'data storage'),
|
|
||||||
new Technology('ASP.NET MVC', 'dynamic content generation'),
|
|
||||||
new Technology('Database Abstraction', 'data access'),
|
|
||||||
new Technology('MySQL', 'data storage'),
|
|
||||||
new Technology('PHP', 'dynamic content generation')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Riehl World News */
|
|
||||||
const riehlWorldNews = new App('riehl-world-news', 'Riehl World News', 'http://riehlworldview.com')
|
|
||||||
riehlWorldNews.categoryId = Category.WORDPRESS
|
|
||||||
riehlWorldNews.frontPageText = 'Riehl news for real people'
|
|
||||||
riehlWorldNews.frontPageOrder = 4
|
|
||||||
riehlWorldNews.indexText = 'Riehl news for real people'
|
|
||||||
riehlWorldNews.techStack = [
|
|
||||||
new Technology('WordPress', 'blogging', true),
|
|
||||||
new Technology('MySQL', 'data storage', true),
|
|
||||||
new Technology('F#', 'custom archive static page generation')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** The Shark Tank */
|
|
||||||
const theSharkTank = new App('the-shark-tank', 'The Shark Tank', 'http://shark-tank.net')
|
|
||||||
theSharkTank.isActive = false
|
|
||||||
theSharkTank.categoryId = Category.WORDPRESS
|
|
||||||
theSharkTank.indexText = 'Florida’s political feeding frenzy'
|
|
||||||
theSharkTank.techStack = [ new Technology('WordPress', 'blogging') ]
|
|
||||||
|
|
||||||
/** The Clearinghouse Management System */
|
|
||||||
var tcms = new App('tcms', 'The Clearinghouse Management System', 'http://tcms.us')
|
|
||||||
tcms.isActive = false
|
|
||||||
tcms.indexText =
|
|
||||||
'Assists a needs clearinghouse in connecting people with needs to people that can help meet those needs'
|
|
||||||
tcms.techStack = [
|
|
||||||
new Technology('PHP', 'the TCMS application logic'),
|
|
||||||
new Technology('WordPress', 'publicly-facing pages and authentication'),
|
|
||||||
new Technology('PostgreSQL', 'application data storage'),
|
|
||||||
new Technology('MySQL', 'WordPress data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
/** Virtual Prayer Room */
|
|
||||||
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.techStack = [
|
|
||||||
new Technology('PHP', 'the application logic'),
|
|
||||||
new Technology('PostgreSQL', 'data storage')
|
|
||||||
]
|
|
||||||
|
|
||||||
export default {
|
|
||||||
|
|
||||||
/** All categories */
|
|
||||||
categories: [
|
|
||||||
new Category(Category.SITES_APPS, 'Web Sites and Applications'),
|
|
||||||
new Category(Category.WORDPRESS, 'WordPress'),
|
|
||||||
new Category(Category.STATIC, 'Static Sites'),
|
|
||||||
new Category(Category.PERSONAL, 'Personal')
|
|
||||||
],
|
|
||||||
|
|
||||||
/** All apps */
|
|
||||||
apps: [
|
|
||||||
aWordFromTheWord,
|
|
||||||
bayVista,
|
|
||||||
cassyFiano,
|
|
||||||
danielJSummers,
|
|
||||||
drMelissaClouthier,
|
|
||||||
emcs,
|
|
||||||
futilityCloset,
|
|
||||||
hardCorpsWife,
|
|
||||||
libertyPundits,
|
|
||||||
linuxResources,
|
|
||||||
mindyMackenzie,
|
|
||||||
myPrayerJournal,
|
|
||||||
nsx,
|
|
||||||
olivet,
|
|
||||||
photographyByMichelle,
|
|
||||||
prayerTracker,
|
|
||||||
riehlWorldNews,
|
|
||||||
tcms,
|
|
||||||
techBlog,
|
|
||||||
theSharkTank,
|
|
||||||
vpr
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core'
|
|
||||||
import { Observable, of } from 'rxjs'
|
|
||||||
|
|
||||||
import Data from './application.data'
|
|
||||||
import { Category, App } from './application.types'
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class ApplicationService {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all categories of apps
|
|
||||||
*/
|
|
||||||
getCategories(): Observable<Category[]> {
|
|
||||||
return of(Data.categories)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all apps
|
|
||||||
*/
|
|
||||||
getApps(): Observable<App[]> {
|
|
||||||
return of(Data.apps)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all applications for the given category ID
|
|
||||||
* @param categoryId The ID of the category for which apps should be retrieved
|
|
||||||
*/
|
|
||||||
getAppsForCategory(categoryId: number): Observable<App[]> {
|
|
||||||
return of(
|
|
||||||
Data.apps
|
|
||||||
.filter(app => app.categoryId === categoryId)
|
|
||||||
.sort((a, b) => a.frontPageOrder - b.frontPageOrder)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a specific app
|
|
||||||
* @param appId The ID of the app to retrieve
|
|
||||||
*/
|
|
||||||
getApp(appId: string): Observable<App> {
|
|
||||||
return of(Data.apps.find(app => app.id === appId))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
/** A category of application */
|
|
||||||
export class Category {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new instance
|
|
||||||
* @param id The ID of the category
|
|
||||||
* @param name The name of the category
|
|
||||||
*/
|
|
||||||
constructor(public id: number, public name: string) {
|
|
||||||
this.id = id
|
|
||||||
this.name = name
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sites/applications not otherwise specified */
|
|
||||||
static SITES_APPS = 1
|
|
||||||
|
|
||||||
/** WordPress sites */
|
|
||||||
static WORDPRESS = 2
|
|
||||||
|
|
||||||
/** Statically generated sites */
|
|
||||||
static STATIC = 3
|
|
||||||
|
|
||||||
/** Daniel's personal sites */
|
|
||||||
static PERSONAL = 99
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A quote from an app */
|
|
||||||
export class Quote {
|
|
||||||
|
|
||||||
/** The full text of the quote */
|
|
||||||
full: string = ''
|
|
||||||
|
|
||||||
/** Shorter portions of the full quote */
|
|
||||||
pull: string[] = []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new instance
|
|
||||||
* @param name The name of the person who provided the quote
|
|
||||||
* @param from What organization the person who provided the quote represents
|
|
||||||
*/
|
|
||||||
constructor(public name: string, public from: string) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A description of a part of the technology stack used */
|
|
||||||
export class Technology {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new instace
|
|
||||||
* @param name The name of the technology
|
|
||||||
* @param usedFor What aspect was addressed by this technology
|
|
||||||
* @param current Whether this technology is currently in use in the solution
|
|
||||||
*/
|
|
||||||
constructor(public name: string, public usedFor: string, public current: boolean = false) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** An application or web site */
|
|
||||||
export class App {
|
|
||||||
|
|
||||||
/** Whether this app is active (default true) */
|
|
||||||
isActive: boolean = true
|
|
||||||
|
|
||||||
/** The ID of the category to which this app belongs (default "Web Sites and Applictions") */
|
|
||||||
categoryId: number = Category.SITES_APPS
|
|
||||||
|
|
||||||
/** Whether to skip displaying an About link on the front page */
|
|
||||||
noAboutLink: boolean = false
|
|
||||||
|
|
||||||
/** Whether the generate a link for an inactive app (defaults to false) */
|
|
||||||
linkInactive: boolean = false
|
|
||||||
|
|
||||||
/** The text to use for the short description in the front page sidebar */
|
|
||||||
frontPageText: string = ''
|
|
||||||
|
|
||||||
/** The order (within category) in which this app should be displayed */
|
|
||||||
frontPageOrder: number = 0
|
|
||||||
|
|
||||||
/** The text to display for the application on this index page */
|
|
||||||
indexText: string = ''
|
|
||||||
|
|
||||||
/** The URL where an archived version of this app may be found */
|
|
||||||
archiveUrl: string = ''
|
|
||||||
|
|
||||||
/** The technology used for this app */
|
|
||||||
techStack: Technology[] = []
|
|
||||||
|
|
||||||
/** Customer quotes */
|
|
||||||
quotes: Quote[] = []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new instance
|
|
||||||
* @param id The ID of the app
|
|
||||||
* @param name The name of the app
|
|
||||||
* @param url The URL of the app
|
|
||||||
*/
|
|
||||||
constructor(public id: string, public name: string, public url: string) { }
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core'
|
|
||||||
import { CommonModule } from '@angular/common'
|
|
||||||
import { RouterModule } from '@angular/router'
|
|
||||||
|
|
||||||
import { AllSolutionsLinkComponent } from './all-solutions-link.component'
|
|
||||||
import { ApplicationComponent } from './application.component'
|
|
||||||
import { ApplicationDetailDirective } from './application-detail.directive'
|
|
||||||
import { ApplicationHeaderComponent } from './application-header/application-header.component'
|
|
||||||
import { ApplicationImageComponent } from './application-image/application-image.component'
|
|
||||||
import { ApplicationListComponent } from './application-list/application-list.component'
|
|
||||||
import { ApplicationListItemComponent } from './application-list-item/application-list-item.component'
|
|
||||||
import { HideSectionComponent } from './hide-section/hide-section.component'
|
|
||||||
import { QuotesComponent } from './quotes/quotes.component';
|
|
||||||
import { SharedModule } from '../shared/shared.module'
|
|
||||||
import { TechnologyComponent } from './technology/technology.component';
|
|
||||||
import { TechStackComponent } from './tech-stack/tech-stack.component';
|
|
||||||
|
|
||||||
import { BayVistaComponent } from './solutions/bay-vista.component'
|
|
||||||
import { BitBadgerBlogComponent } from './solutions/bit-badger-blog.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';
|
|
||||||
import { MindyMackenzieComponent } from './solutions/mindy-mackenzie.component';
|
|
||||||
import { MyPrayerJournalComponent } from './solutions/my-prayer-journal.component';
|
|
||||||
import { NsxComponent } from './solutions/nsx.component';
|
|
||||||
import { OlivetBaptistComponent } from './solutions/olivet-baptist.component';
|
|
||||||
import { PhotographyByMichelleComponent } from './solutions/photography-by-michelle.component';
|
|
||||||
import { PrayerTrackerComponent } from './solutions/prayer-tracker.component'
|
|
||||||
import { RiehlWorldNewsComponent } from './solutions/riehl-world-news.component';
|
|
||||||
import { SharkTankComponent } from './solutions/shark-tank.component';
|
|
||||||
import { TcmsComponent } from './solutions/tcms.component';
|
|
||||||
import { VirtualPrayerRoomComponent } from './solutions/virtual-prayer-room.component'
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
AllSolutionsLinkComponent,
|
|
||||||
ApplicationComponent,
|
|
||||||
ApplicationDetailDirective,
|
|
||||||
ApplicationHeaderComponent,
|
|
||||||
ApplicationImageComponent,
|
|
||||||
ApplicationListComponent,
|
|
||||||
ApplicationListItemComponent,
|
|
||||||
BayVistaComponent,
|
|
||||||
BitBadgerBlogComponent,
|
|
||||||
CassyFianoComponent,
|
|
||||||
DrMelissaClouthierComponent,
|
|
||||||
EmeraldMountainChristianSchoolComponent,
|
|
||||||
FutilityClosetComponent,
|
|
||||||
HardCorpsWifeComponent,
|
|
||||||
HideSectionComponent,
|
|
||||||
LibertyPunditsComponent,
|
|
||||||
MindyMackenzieComponent,
|
|
||||||
MyPrayerJournalComponent,
|
|
||||||
NsxComponent,
|
|
||||||
OlivetBaptistComponent,
|
|
||||||
PhotographyByMichelleComponent,
|
|
||||||
PrayerTrackerComponent,
|
|
||||||
QuotesComponent,
|
|
||||||
RiehlWorldNewsComponent,
|
|
||||||
SharkTankComponent,
|
|
||||||
TcmsComponent,
|
|
||||||
TechnologyComponent,
|
|
||||||
TechStackComponent,
|
|
||||||
VirtualPrayerRoomComponent
|
|
||||||
],
|
|
||||||
entryComponents: [
|
|
||||||
BayVistaComponent,
|
|
||||||
BitBadgerBlogComponent,
|
|
||||||
CassyFianoComponent,
|
|
||||||
DrMelissaClouthierComponent,
|
|
||||||
EmeraldMountainChristianSchoolComponent,
|
|
||||||
FutilityClosetComponent,
|
|
||||||
HardCorpsWifeComponent,
|
|
||||||
LibertyPunditsComponent,
|
|
||||||
MindyMackenzieComponent,
|
|
||||||
MyPrayerJournalComponent,
|
|
||||||
NsxComponent,
|
|
||||||
OlivetBaptistComponent,
|
|
||||||
PhotographyByMichelleComponent,
|
|
||||||
PrayerTrackerComponent,
|
|
||||||
RiehlWorldNewsComponent,
|
|
||||||
SharkTankComponent,
|
|
||||||
TcmsComponent,
|
|
||||||
VirtualPrayerRoomComponent
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
RouterModule,
|
|
||||||
SharedModule
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
ApplicationComponent,
|
|
||||||
ApplicationListComponent
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class ApplicationsModule { }
|
|
@ -1,4 +0,0 @@
|
|||||||
<h3 (click)="toggle()">{{ heading }}<span class="arrow" [innerHtml]="label"></span></h3>
|
|
||||||
<div *ngIf="shown" [@slideInOut]>
|
|
||||||
<ng-content></ng-content>
|
|
||||||
</div>
|
|
@ -1,6 +0,0 @@
|
|||||||
h3:hover
|
|
||||||
cursor: hand
|
|
||||||
cursor: pointer
|
|
||||||
.arrow
|
|
||||||
font-size: .75rem
|
|
||||||
padding-left: 1rem
|
|
@ -1,38 +0,0 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core';
|
|
||||||
import { trigger, transition, style, animate, group } from '@angular/animations';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-hide-section',
|
|
||||||
templateUrl: './hide-section.component.html',
|
|
||||||
styleUrls: ['./hide-section.component.sass'],
|
|
||||||
animations: [
|
|
||||||
trigger('slideInOut', [
|
|
||||||
transition(':enter', [
|
|
||||||
style({ opacity: 0 }),
|
|
||||||
animate('500ms ease-in', style({ opacity: 1 }))
|
|
||||||
]),
|
|
||||||
transition(':leave', [
|
|
||||||
style({opacity: 1}),
|
|
||||||
animate('500ms ease-in', style({ opacity: 0 }))
|
|
||||||
])
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class HideSectionComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() heading: string
|
|
||||||
|
|
||||||
label = '▼'
|
|
||||||
|
|
||||||
shown = false
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
toggle() {
|
|
||||||
this.shown = !this.shown
|
|
||||||
this.label = this.shown ? '▲' : '▼'
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
<div *ngIf="(quotes || []).length > 0">
|
|
||||||
<h3>The Business Impact</h3>
|
|
||||||
<blockquote *ngFor="let quote of quotes">
|
|
||||||
<p class="quote" [innerHtml]="quote.full"></p>
|
|
||||||
<p class="source">
|
|
||||||
— <strong>{{ quote.name }}</strong>
|
|
||||||
<span *ngIf="quote.from">, {{ quote.from }}</span>
|
|
||||||
</p>
|
|
||||||
</blockquote>
|
|
||||||
</div>
|
|
@ -1,9 +0,0 @@
|
|||||||
blockquote
|
|
||||||
border-left: solid 1px darkgray
|
|
||||||
margin-left: 25px
|
|
||||||
padding-left: 15px
|
|
||||||
.quote
|
|
||||||
font-style: italic
|
|
||||||
.source
|
|
||||||
text-align: right
|
|
||||||
padding-right: 60px
|
|
@ -1,18 +0,0 @@
|
|||||||
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() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
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`
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
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
|
|
||||||
<abbr title="Federal Emergency Management Agency">FEMA</abbr> during Hurricane Katrina relief and recovery
|
|
||||||
efforts, and they are a relay point for each year’s
|
|
||||||
<a href="https://www.samaritanspurse.org/what-we-do/operation-christmas-child/">Operation Christmas Child</a>
|
|
||||||
campaign.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
In late 2013, the authors of their current website were no longer around, and no one could get to the site to
|
|
||||||
update it.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We developed and continue to maintain a fast, static website that can be updated by multiple trained church
|
|
||||||
members. The site also has a repository for their sermons dating back to January 2014, and a podcast feed that
|
|
||||||
gives their ministry a global reach.
|
|
||||||
</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
Initially, we set up a WordPress-based site, where multiple people could have the ability to maintain the site.
|
|
||||||
We manually downloaded all the publically-accessible parts of their old site, and used that content to form the
|
|
||||||
basis for the new side, updating outdated information along the way. We maintained the same look-and-feel, but
|
|
||||||
soon moved to a more mobile-friendly layout.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In 2016, we determined that we were the only ones updating the site, so we transformed the site to use a static
|
|
||||||
site generator; this resulted in fast page loads, with automation providing scheduled updates. We also wrote a
|
|
||||||
custom template for the podcast feed, which is also generated as a static file.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In 2019, we <a href="https://github.com/bayvistabc/www.bayvista.org">open sourced</a> the site's source code.
|
|
||||||
We also set up Azure Pipelines to automatically build and deploy the site both on demand and on a schedule.
|
|
||||||
Finally, we trained other church members on updating the site's contents and the podcast feed.
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
Daniel needed a place to journal his learning journey with the Linux operating system, and thought that allowing
|
|
||||||
others read this journal would help them learn as well.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
<em>The Bit Badger Blog</em> contains that journal, plus tech tips and information for many different aspects of
|
|
||||||
technology. It is written, maintained, and hosted by Bit Badger Solutions.
|
|
||||||
</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
The initial posts were titled “My Linux Adventure,” and existed as static files that were edited to
|
|
||||||
add each post. Daniel then wrote a rudimentary system that stored the posts in a database, which meant that the
|
|
||||||
entire site did not need manual changes – what a breakthrough! :)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Over time, the <em>Bit Badger Blog</em> (and the <em>DJS Consulting Tech Blog</em> before it) has served as a
|
|
||||||
place to support <em>(now inactive)</em> WordPress plug-ins, and go in depth on servers, databases, programming
|
|
||||||
languages, and open-source software. It has also served as a useful live website for learning and
|
|
||||||
experimentation with different content management systems and blogging tools. It has existed in at least 8
|
|
||||||
different tools, with links preserved as systems change.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
It is currently a statically-generated site, utilizing <a href="https://hexo.io">Hexo</a>, and its code is
|
|
||||||
<a href="https://github.com/bit-badger/blog.bitbadger.solutions">open source</a>. New posts are infrequent,
|
|
||||||
but the information it has is good. It may have more behind-the-scenes posts about future open-source efforts.
|
|
||||||
Stay tuned!
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-bit-badger-blog',
|
|
||||||
templateUrl: './bit-badger-blog.component.html'
|
|
||||||
})
|
|
||||||
export class BitBadgerBlogComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Cassy Fiano (now Cassy Chesser) began blogging back in 2007 on Blogger. She worked hard to network with other
|
|
||||||
bloggers, wrote prolifically, and gained a large audience with her coverage of life issues and of Sarah Palin as
|
|
||||||
the first female Republican vice-presidential nominee.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
With her success, Cassy was quickly outgrowing Blogger. She was interested in moving to a different platform;
|
|
||||||
specifically, Movable Type, as she had some authoring experience with that platform.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We migrated her content to a WordPress site, and customized a theme to look very similar to her Blogger theme
|
|
||||||
(which she liked). We maintained the site, and began hosting it a few years later.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>Cassy formally decommissioned this site in early 2014.</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
Initially, we assisted her with finding a theme, and customized it. We also modified her old Blogger template
|
|
||||||
to send redirect users to her new blog after displaying a note that the blog had moved. A few years later, we
|
|
||||||
developed an advertising banner to generate income from her writing.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In July 2012, we began hosting the site, as we were already hosting her military wife blog
|
|
||||||
<a routerLink="/solutions/hard-corps-wife" title="Hard Corps Wife | Bit Badger Solutions">Hard Corps Wife</a>.
|
|
||||||
When the time came to decommission the site, we backed up the data and ensured she had it.
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Dr. Melissa Clouthier (now Mackenzie) blogged from the political right; she also covered health issues and social
|
|
||||||
media techniques and utilization.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
She had seen our work with <a routerLink="/solutions/cassy-fiano"
|
|
||||||
title="Cassy Fiano | Bit Badger Solutions">Cassy</a>’s site, also wanted to move off Blogger; however, she
|
|
||||||
did not want to lose her years of posts up to that point.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We created a custom theme for her site, imported the content into a WordPress site, and created a specialized
|
|
||||||
front-page template. She obtained hosting elsewhere; Bit Badger Solutions maintained it there.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<small><em>(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.)</em></small>
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>Melissa decommissioned this site in 2018; we took final snapshots of the data before shutting it down.</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
Initially, we created the theme based off another well-known blogger's site, which had been developed by one of
|
|
||||||
WordPress's core contributors. We also advised on the type of hosting she would need for her site, and moved
|
|
||||||
seveal domains there. We also took care of regular backups of her data.
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
They had a website with very basic information and very little styling; they also had no way of updating it.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
In 2004, we developed a theme that brought it in line with the design of their printed materials, adding the
|
|
||||||
school calendar of events and the entirety of their Parent Information Packet, giving prospective families the
|
|
||||||
information the needed to determine if the school was a good fit for their students.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>
|
|
||||||
In 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 <a href="http://emcspatriots.org"
|
|
||||||
title="EMCS Patriots">EMCSpatriots.org</a>.
|
|
||||||
</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
Initially, we downloaded the content from their old site, and put it into a custom PHP-based framework. We
|
|
||||||
then added a database of events, and a calendar page that read that database, enabling us to display multiple
|
|
||||||
years, as well as future and past years. The design of the online information packet looked like a tabbed
|
|
||||||
notebook, with each page highlighting a different tab.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In 2011, we switched the site to use ASP.NET MVC instead of the custom PHP solution, and migrated the data from
|
|
||||||
MySQL to PostgreSQL; these efforts increased the performance of the site.
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Futility Closet exists as a place to give people a break from the dullness of work, by providing puzzles,
|
|
||||||
anecdotes, and more. They also publish a weekly podcast highlighting “forgotten stories from the pages of
|
|
||||||
history,” along with story updates and lateral thinking puzzles.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
The site was running on a shared host, but was growing too large for that platform. The site had also suffered
|
|
||||||
regular security breaches.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We architected an environment that would support a Reddit or Slashdot deluge of requests, and moved the site to
|
|
||||||
an implementation of that environment. We continue to maintain that environment and back up data and files for
|
|
||||||
the over 10,000 posts.
|
|
||||||
</p>
|
|
||||||
<app-quotes [quotes]="app.quotes"></app-quotes>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
In mid-2010, we obtained a backup of the previous site, and looked through it to ensure that none of the
|
|
||||||
breaches had made any permanent changes to the site's structure and data. We also locked down the new server
|
|
||||||
(hosted on Rackspace Cloud) to only required protocols, training the client on SSH so that they could have
|
|
||||||
access. We also stood up nginx as the front-end server, boosting performance significantly while requiring a
|
|
||||||
much smaller server.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In 2015, we began hosting Futility Closet (using Digital Ocean).
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Our existing client <a routerLink="/solutions/cassy-fiano"
|
|
||||||
title="Cassy Fiano | Bit Badger Solutions">Cassy Fiano</a>
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>Cassy (now Chesser) wanted a separate place from which to chronicle her experience as a military spouse.</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
In mid-2010, we set up her domain name, created a WordPress site, and customized the header and sidebar for her
|
|
||||||
selected theme. We also hosted and maintained the site for the duration of its run.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>In 2013, Cassy shifted priorities and closed this site down.</p>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
<a routerLink="/solutions/dr-melissa-clouthier">Melissa Clouthier</a>, Bill Dupray, and Clyde Middleton, all
|
|
||||||
established conservative bloggers, started a joint venture called <em>Liberty Pundits</em>.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
Bill and Clyde had a significant amount of content on a prior site. As they were starting this with established
|
|
||||||
authors, they needed a site that would handle their expected traffic spikes on popular posts.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
In early 2010, we migrated their content from a custom solution into WordPress's database; we then set them up on
|
|
||||||
the same host where their podcast was being distributed. However, the combination of theme complexity and traffic
|
|
||||||
overwhelmed that server, so we configured a standalone server with more memory and more efficient software; this
|
|
||||||
allowed them to routinely eclipse 100,000 views per day, most of those coming on posts within the first few
|
|
||||||
hours.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>
|
|
||||||
The site closed in late 2011, as its authors closed their joint venture and moved on to other sites and topics.
|
|
||||||
</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
Before we could migrate the data from <em>Patriot Room</em>, Bill and Clyde's prior home, we had to get into
|
|
||||||
the server and determine how data was stored in the custom solution. Once we identified where all the data was,
|
|
||||||
we wrote a custom migration script to shape the data the way WordPress needed it.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Mindy Mackenzie, the prior Chief Performance Officer of Beam, Inc., is known as the “Velvet Hammer”
|
|
||||||
for her tough-yet-caring style of leadership. She is a <em>Wall Street Journal</em> best-selling author of the
|
|
||||||
book <em>The Courage Solution: The Power of Truth-Telling with Your Boss, Peers, and Team</em>, and the creator
|
|
||||||
and host of the annual <em>You First Integrative Leadership Summit</em>, equipping women of influence to reach
|
|
||||||
even greater heights.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
Mindy was dissatisfied with the value she was receiving with her current web designer and host; in advance of
|
|
||||||
her book launch, she needed a more
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We took over hosting her site, updating it regularly for the book launch, and highlighting her media appearances
|
|
||||||
in conjunction with that launch. We also created and continue to maintain the pages for her <em>You First
|
|
||||||
Integrative Leadership Summit</em>, including online registration.
|
|
||||||
</p>
|
|
||||||
<app-quotes [quotes]="app.quotes"></app-quotes>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
In late 2015, We assumed maintenance of her site several months in advance of the book launch. We created a
|
|
||||||
custom WordPress type to highlight her Media Appearances, automatically ordered from most recent to older. She
|
|
||||||
had a lot of short video content, and we implemented code that displays a different video each week on the
|
|
||||||
front page.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In early 2018, we developed the pages for her <em>You First Integrative Leadership Summit</em>, with speaker
|
|
||||||
bios, conference schedule, and an application form. We have continued to maintain these pages across the 2019
|
|
||||||
and 2020 summits.
|
|
||||||
</p>
|
|
||||||
<p>We continue to provide backups, WordPress support, and content updates for Mindy’s site.</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-mindy-mackenzie',
|
|
||||||
templateUrl: './mindy-mackenzie.component.html'
|
|
||||||
})
|
|
||||||
export class MindyMackenzieComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
Daniel wanted to maintain a prayer journal, where he could record the prayer requests for which he had prayed,
|
|
||||||
and the answer that eventually came to that request. He didn't want to do that on paper for several reasons
|
|
||||||
– it's easy to lose, a long-running request can run out of space to make notes, etc.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We created a site where users can enter requests, pray through lists of these requests, make notes on them, and
|
|
||||||
follow them through until they are answered. The site stores no identifying information, and works well on both
|
|
||||||
desktop and mobile. Bit Badger Solutions hosts and maintains the instance of the site linked above.
|
|
||||||
</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
Development of myPrayerJournal began in earnest in early 2017. As we were using this to learn new techniques,
|
|
||||||
we ended up trying a host of different front and back end technologies before settling on Vue.js for the front
|
|
||||||
end and Giraffe for the back end. This combination works well, and we wrote up an 8-post series entitled
|
|
||||||
<a href="https://blog.bitbadger.solutions/2018/a-tour-of-myprayerjournal/introduction.html">"A Tour of
|
|
||||||
myPrayerJournal"</a> over on the <em>Bit Badger Blog</em> that steps through all aspects of version 1 of this
|
|
||||||
application.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Version 2 changed to a Material Design interface, and we changed the data store from PostgreSQL to RavenDB, an
|
|
||||||
excellent document database. As this is an open-source project, anyone can review the source code on
|
|
||||||
<a href="https://github.com/bit-badger/myPrayerJournal">GitHub</a>; we also track open issues there.
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-my-prayer-journal',
|
|
||||||
templateUrl: './my-prayer-journal.component.html'
|
|
||||||
})
|
|
||||||
export class MyPrayerJournalComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
In January 2008, a few members of <a href="http://hoffmantown.org" title="Hoffmantown Church">Hoffmantown
|
|
||||||
Church</a> in Albuquerque, New Mexico had an idea. The ABC show
|
|
||||||
<em><a href="http://abc.go.com/shows/extreme-makeover-home-edition">Extreme Makeover: Home Edition</a></em> had
|
|
||||||
just done <a href="http://abc.go.com/shows/extreme-makeover-home-edition/episode-detail/martinez-family/224884"
|
|
||||||
title="Martinez Family • Extreme Makeover: Home Edition">a build for a pastor in the “war zone”
|
|
||||||
area of town</a>, and this brought attention to Gerald Martinez and the work he had done to help clean up this
|
|
||||||
area of town. Through <a href="http://www.loveincabq.org/" title="Love INC of South Albuquerque">Love INC of
|
|
||||||
South Albuquerque</a>, they learned that there were many other homes in that area that could use the “Ty
|
|
||||||
Pennington touch.” While the goal was not to knock down homes and build new ones, the goal was no less
|
|
||||||
extreme. The goal of the “Not So Extreme Makeover: Community Edition” was to help 50 families in 5
|
|
||||||
days during spring break week in 2008.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
An effort of this magnitude, happening this quickly, would be unmanageable without software support. It would
|
|
||||||
also require a lot of paperwork, and a lot of people processing that paperwork.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We obtained the domain name and stood up the public website quickly using WordPress, which also allowed the
|
|
||||||
coordinators to put content up. We then developed an application (NSXapp) where volunteers could sign up for
|
|
||||||
“X Week”, with over 80 different skill, talent, and ability categories. We then created a way to
|
|
||||||
identify families and their needs, and a place for people with donations to let us know what they would be. From
|
|
||||||
there, we created the ability to begin matching needs with goods (stuff) and abilities (people), organizing the
|
|
||||||
stuff into donated trailers and people into teams. During X Week, NSXapp generated schedules and reports that
|
|
||||||
were used to help guide the teams as they executed their projects.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>
|
|
||||||
From an idea in January, “Not So Extreme Makeover: Community Edition” was able to help 57 families
|
|
||||||
by the end of X Week on March 29th. When Love INC saw how NSXapp worked, they expressed an interest in a version
|
|
||||||
that would allow them to handle these same areas on an ongoing basis; this became
|
|
||||||
<a routerLink="/solutions/tcms" title="The Clearinghouse Management System | Bit Badger Solutions">TCMS</a>.
|
|
||||||
Finally, there is a <a href="https://nsx.archive.bitbadger.solutions">snapshot of the NSX public site</a> that
|
|
||||||
serves as a record of those three months in 2008.
|
|
||||||
</p>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-nsx',
|
|
||||||
templateUrl: './nsx.component.html'
|
|
||||||
})
|
|
||||||
export class NsxComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Olivet Baptist Church was a Southern Baptist church in Gulfport, Mississippi, who had seen our work with
|
|
||||||
<a routerLink="/solutions/bay-vista" title="Bay Vista Baptist Church | Bit Badger Solutions">Bay Vista</a> and
|
|
||||||
wanted something similar.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>Olivet had no online presence.</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
Initially, we set up a WordPress site, configured it, and established a podcast feed; we also advised them on how
|
|
||||||
to register that feed in iTunes. A few years later, we converted the site to behave like an app, where it could
|
|
||||||
be installed as an icon, allowing quick access.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>
|
|
||||||
When the church closed its doors on February 24th, 2019, we converted the app-behaving site back to a static web
|
|
||||||
site, set up an archive site, and worked with their personnel to ensure that the podcast links are all still
|
|
||||||
available. We continue to host that archive site and podcast content.
|
|
||||||
</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
In 2014, we registered the domain name for the church. They had expressed a desire to do as much of the content
|
|
||||||
of the site themselves, so we supported them as they worked through its initial setup. After the site was
|
|
||||||
originally set up, though, updates were rare (apart from the weekly podcast episodes), so we converted it to be
|
|
||||||
a statically-generated site.
|
|
||||||
<p>
|
|
||||||
In 2018, we modified the site to be a Progressive Web Application (PWA), which allows users to
|
|
||||||
“install” the site, like an app, to their phone’s home screen. The site was also still
|
|
||||||
accessible from the web via a browser. We converted the static content to generate page fragments that the PWA
|
|
||||||
would load, providing the same navigation experience as before.
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-olivet-baptist',
|
|
||||||
templateUrl: './olivet-baptist.component.html'
|
|
||||||
})
|
|
||||||
export class OlivetBaptistComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Michelle Summers had been photographing her children for years. When her sons were on sports teams, she was
|
|
||||||
disappointed with the cost of team photography, and felt that she could do a better job at a lower cost. She
|
|
||||||
specialized in outdoor photography of families, children, and sports teams, as well as maternity photography and
|
|
||||||
holiday cards.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
Michelle needed a site to showcase her previous work, as well as a place to allow her customers to view their
|
|
||||||
proofs before selecting prints.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We created a WordPress site with image galleries for her existing work, and utilized a custom plug-in to support
|
|
||||||
online proofs. This site was eventually replaced with one that had a matching Windows application; this
|
|
||||||
application took a set of photos, resized them, applied a watermark, and created the proof gallery without having
|
|
||||||
to even go to the site.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>
|
|
||||||
As Michelle is no longer doing professional photography, the current version of this site is a simple thank-you
|
|
||||||
to her customers from 2007-2014.
|
|
||||||
</p>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-photography-by-michelle',
|
|
||||||
templateUrl: './photography-by-michelle.component.html'
|
|
||||||
})
|
|
||||||
export class PhotographyByMichelleComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
Back in 2005, Daniel was responsible for keeping up with prayer requests for his Sunday School class. However,
|
|
||||||
simply sending out a mass e-mail has some significant drawbacks - everyone's e-mail address is visible to
|
|
||||||
everyone else; mass e-mails are more likely to be flagged as suspicious; and it is difficult to have a single
|
|
||||||
“latest and greatest” list of members.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We wrote a site so we could enter prayer requests and class members; this site would then send individual e-mails
|
|
||||||
to each member. When requests were 15 days old, they would drop off the list. From there, PrayerTracker has grown
|
|
||||||
to support multiple churches and groups within those churches, and the user interface is available in both
|
|
||||||
English <em>y Español</em>. Bit Badger Solutions offers use of this site for free to any church, Sunday School
|
|
||||||
class, or small group that desires a tool to help them establish a continuous list of prayer requests.
|
|
||||||
</p>
|
|
||||||
<app-hide-section heading="The Process">
|
|
||||||
<p>
|
|
||||||
The first reimagining of PrayerTracker occurred in 2011; this was when we moved to a more modern (at the time)
|
|
||||||
framework (ASP MVC 3), building in the multi-church/multi-group security additions, and posturing it for an
|
|
||||||
interface with <a routerLink="/solutions/virtual-prayer-room"
|
|
||||||
title="Virtual Prayer Room | Bit Badger Solutions">Virtual Prayer Room</a>. A year later, a visiting missionary
|
|
||||||
saw the site and liked it, but needed the site (including the online help) in Spanish; we released version 4 a
|
|
||||||
few months later which brought this support.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In late 2014, version 5 moved to a MongoDB data store, as we had some problems with columns not being large
|
|
||||||
enough for some requests. In early 2017, we released version 6, which took PrayerTracker into the .NET Core
|
|
||||||
environment; we also moved the data back to PostgreSQL, as it now supported the sizes we needed.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Version 7 was released in mid-2018, bringing full mobile accessibility and an upgrade to a modern, ultra-fast
|
|
||||||
web framework (Giraffe). In early 2019, version 7.1 was the first release for PrayerTracker as an
|
|
||||||
<a href="https://github.com/bit-badger/PrayerTracker">open source project</a>. Right on its heels, version 7.2
|
|
||||||
moved the embedded help files to GitHub Pages; this made the web application more streamlined.
|
|
||||||
</p>
|
|
||||||
</app-hide-section>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Dan Riehl began blogging as <em>The Carnivorous Conservative</em> back in 2004, specializing in the areas of
|
|
||||||
crime and politics. He changed to <em>Riehl World View</em> a short time later, and writes both news and opinion
|
|
||||||
pieces. He was a prolific blogger, publishing over 15 posts a day on most days.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
He wanted to take his blog in a different direction, and was having trouble getting his Movable Type blog do move
|
|
||||||
with him.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We stood up a WordPress site on a server he procured. We then assisted him in selecting a theme and customized it
|
|
||||||
to his liking. Finally, we wrote custom migration code to get his past body of work into the new site. In 2018,
|
|
||||||
we generated static files for most of his prior posts, to give him a clean slate for a new direction. We continue
|
|
||||||
to maintain and support <em>Riehl World News</em>.
|
|
||||||
</p>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-riehl-world-news',
|
|
||||||
templateUrl: './riehl-world-news.component.html'
|
|
||||||
})
|
|
||||||
export class RiehlWorldNewsComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
<em>The Shark Tank</em> is a news and opinion site centered on south Florida politics (and the state at large).
|
|
||||||
They provided extensive coverage of Rep. Allen West’s winning campaign in 2010, and continue their focused
|
|
||||||
news and opinion on current political races.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
They were displeased with their current theme; it was struggling with the amount of content they were producing.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
They had identified a theme that would better suit their needs. We set it up, ensuring that their content would
|
|
||||||
fit in the new theme’s requirements, and helped them turn off parts that they didn’t need. We also
|
|
||||||
converted the social media connections from their old site to a style that would work nicely in the new theme.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>This was all they needed; they returned their focus to their writing.</p>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-shark-tank',
|
|
||||||
templateUrl: './shark-tank.component.html'
|
|
||||||
})
|
|
||||||
export class SharkTankComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Love INC of South Albuquerque runs a “needs clearinghouse”; they have volunteers who accept
|
|
||||||
donations, and people contact them with their needs. They are then able to match the person who needs something
|
|
||||||
with that thing, or with someone who can assist them.
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
The files in their offices were multiplying; ensuring people’s needs are not missed, while ensuring that
|
|
||||||
their clients were not taking advantage of their services, required a lot of paper. They were tracking volunteers
|
|
||||||
on a spreadsheet, but their contact info was in yet another file. Having worked with us on the
|
|
||||||
<a routerLink="/solutions/nsx"
|
|
||||||
title="Not So Extreme Makeover: Community Edition | Bit Badger Solutions">“Not So Extreme Makeover:
|
|
||||||
Community Edition”</a>, and thought that the solution we developed for that project would help them.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
We adapted NSXapp to handle an ongoing stream of people, volunteers, and donations. This enabled them to spend
|
|
||||||
more time with the people who needed help. The WordPress front end also served as their public website, and
|
|
||||||
allowed them to manage the volunteers who were using the system.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>
|
|
||||||
Love INC of South Albuquerque found a SalesForce system that would do things very similar to TCMS, and was able
|
|
||||||
to get in on a program that let them use it at no cost; TCMS was decommissioned in 2014.
|
|
||||||
</p>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { AppDetailComponent } from './app-detail.component'
|
|
||||||
import { App } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-tcms',
|
|
||||||
templateUrl: './tcms.component.html'
|
|
||||||
})
|
|
||||||
export class TcmsComponent extends AppDetailComponent {
|
|
||||||
|
|
||||||
@Input() app: App
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
<app-page-title [title]="pageTitle"></app-page-title>
|
|
||||||
<app-application-header [app]="app"></app-application-header>
|
|
||||||
<div class="app-info">
|
|
||||||
<article class="content">
|
|
||||||
<app-application-image [app]="app"></app-application-image>
|
|
||||||
<h3>The Client</h3>
|
|
||||||
<p>
|
|
||||||
Our existing client <a href="http://hoffmantown.org" title="Hoffmantown Church">Hoffmantown Church</a> in
|
|
||||||
Albuquerque, New Mexico, with whom we had worked on the <a routerLink="/solutions/nsx/"
|
|
||||||
title="Not So Extreme Makeover: Community Edition | Bit Badger Solutions">Not So Extreme Makeover: Community
|
|
||||||
Edition</a>
|
|
||||||
</p>
|
|
||||||
<h3>The Problem</h3>
|
|
||||||
<p>
|
|
||||||
Hoffmantown 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.
|
|
||||||
</p>
|
|
||||||
<h3>The Solution</h3>
|
|
||||||
<p>
|
|
||||||
The development of Virtual Prayer Room extended the prayer room to anywhere a 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.
|
|
||||||
</p>
|
|
||||||
<h3>The Epilogue</h3>
|
|
||||||
<p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
<app-tech-stack [stack]="app.techStack"></app-tech-stack>
|
|
||||||
<app-all-solutions-link></app-all-solutions-link>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
<div *ngIf="(stack || []).length > 0">
|
|
||||||
<app-hide-section heading="The Technology Stack">
|
|
||||||
<div *ngIf="currentStack.length > 0">
|
|
||||||
<p><small><strong>Current:</strong></small></p>
|
|
||||||
<ul>
|
|
||||||
<app-technology *ngFor="let tech of currentStack" [tech]="tech"></app-technology>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="priorStack.length > 0">
|
|
||||||
<p *ngIf="currentStack.length > 0"><small><strong>Previously:</strong></small></p>
|
|
||||||
<ul>
|
|
||||||
<app-technology *ngFor="let tech of priorStack" [tech]="tech"></app-technology>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</app-hide-section>
|
|
||||||
</div>
|
|
@ -1,4 +0,0 @@
|
|||||||
p
|
|
||||||
margin-bottom: 0
|
|
||||||
ul
|
|
||||||
margin-top: 0
|
|
@ -1,28 +0,0 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { Technology } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-tech-stack',
|
|
||||||
templateUrl: './tech-stack.component.html',
|
|
||||||
styleUrls: ['./tech-stack.component.sass']
|
|
||||||
})
|
|
||||||
export class TechStackComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() stack: Technology[]
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
/** The currently-used technologies */
|
|
||||||
get currentStack() {
|
|
||||||
return this.stack.filter(p => p.current)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The previously-used technologies */
|
|
||||||
get priorStack() {
|
|
||||||
return this.stack.filter(p => !p.current)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
<li>
|
|
||||||
<a *ngIf="hasLink(tech.name)" [href]="techLinks[tech.name]" target="_blank">{{ tech.name }}</a>
|
|
||||||
<span *ngIf="!hasLink(tech.name)">{{ tech.name }}</span>
|
|
||||||
for {{ tech.usedFor }}
|
|
||||||
</li>
|
|
@ -1,53 +0,0 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core'
|
|
||||||
|
|
||||||
import { Technology } from '../application.types'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-technology',
|
|
||||||
templateUrl: './technology.component.html',
|
|
||||||
styleUrls: ['./technology.component.sass']
|
|
||||||
})
|
|
||||||
export class TechnologyComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() tech: Technology
|
|
||||||
|
|
||||||
/** External links to technology products */
|
|
||||||
get techLinks() {
|
|
||||||
return {
|
|
||||||
'ASP.NET MVC': 'https://dotnet.microsoft.com/apps/aspnet/mvc',
|
|
||||||
Azure: 'https://azure.microsoft.com/',
|
|
||||||
'BlogEngine.NET': 'http://www.dotnetblogengine.net/',
|
|
||||||
'Database Abstraction': 'https://github.com/danieljsummers/DatabaseAbstraction',
|
|
||||||
'Digital Ocean': 'https://www.digitalocean.com/',
|
|
||||||
Giraffe: 'https://github.com/giraffe-fsharp/Giraffe',
|
|
||||||
GitHub: 'https://github.com/',
|
|
||||||
'GitHub Pages': 'https://pages.github.com/',
|
|
||||||
Hexo: 'https://hexo.io/',
|
|
||||||
Hugo: 'https://gohugo.io/',
|
|
||||||
Jekyll: 'https://jekyllrb.com/',
|
|
||||||
MongoDB: 'https://www.mongodb.com/',
|
|
||||||
MySQL: 'https://www.mysql.com/',
|
|
||||||
myWebLog: 'https://github.com/bit-badger/myWebLog',
|
|
||||||
nginx: 'http://nginx.org/',
|
|
||||||
Orchard: 'https://orchardproject.net/',
|
|
||||||
PHP: 'https://www.php.net/',
|
|
||||||
PostgreSQL: 'https://www.postgresql.org/',
|
|
||||||
'Rackspace Cloud': 'https://www.rackspace.com/cloud',
|
|
||||||
RavenDB: 'https://ravendb.net/',
|
|
||||||
RethinkDB: 'https://rethinkdb.com/',
|
|
||||||
'SQL Server': 'https://www.microsoft.com/en-us/sql-server/',
|
|
||||||
'Vue.js': 'https://vuejs.org/',
|
|
||||||
WordPress: 'https://wordpress.org'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
/** Whether there is a link for a given product */
|
|
||||||
hasLink(product: string) {
|
|
||||||
return this.techLinks[product] !== undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
<app-page-title title="Information Publicizing Solutions"></app-page-title>
|
|
||||||
<article class="content auto">
|
|
||||||
<h1>Information Publicizing and Blogging</h1>
|
|
||||||
<p>
|
|
||||||
In the early days of the World Wide Web, it was known as the "information superhighway." From its inception, the
|
|
||||||
web's primary goal is information. The open nature of the Internet allows anyone, anywhere to say anything,
|
|
||||||
provided they can connect a machine to the network. In fact, there are software products to handle everything
|
|
||||||
except creating the content; all you have to bring is the ability to form a coherent thought, and type that
|
|
||||||
thought into a box. <a href="https://wordpress.org" title="WordPress">WordPress</a> is one of the most popular
|
|
||||||
<abbr title="Web Log">blog</abbr>ging platforms in use today; it allows authors to concentrate on the content of
|
|
||||||
their websites, rather than forcing authors to turn into programmers.
|
|
||||||
</p>
|
|
||||||
<h2>Custom-Built Sites</h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
We developed and maintained the site for <a href="http://www.emeraldmountainchristianschool.org">Emerald
|
|
||||||
Mountain Christian School</a>
|
|
||||||
<small> (<a routerLink="/solutions/emerald-mountain-christian-school" title="Emerald Mountain Christian School | Bit Badger Solutions">about</a>)</small>
|
|
||||||
for 9 years, where they had information about the type of curriculum they teach, the school's 40+-year history,
|
|
||||||
a calendar of events, and how to get more information.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
We built and maintained the site for <a href="https://www.summershome.org">Photography by Michelle</a>
|
|
||||||
<small> (<a routerLink="/solutions/photography-by-michelle" title="Photography by Michelle | Bit Badger Solutions">about</a>)</small>,
|
|
||||||
which had information, prices, and samples of the photographer's work, as well as the ability for customers to
|
|
||||||
view proofs and make photo selections online.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
The site for <a href="https://bayvista.org" title="Bay Vista Baptist Church">Bay Vista Baptist Church</a>
|
|
||||||
<small> (<a routerLink="/solutions/bay-vista" title="Bay Vista Baptist Church | Bit Badger Solutions">about</a>)</small>
|
|
||||||
utilizes a "static site generator," where the entire site is generated from source files, then served. It
|
|
||||||
requires no back-end database, which means that the server can send pages as fast as its clients can take them.
|
|
||||||
This site even has a generated podcast feed! Adding content to these types of sites requires a bit more
|
|
||||||
technical knowledge beyond "typing text in a box," but it is a great way to build ultra-fast, scalable web
|
|
||||||
sites.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
This site is a single-page application (SPA) utilizing the <a href="https://angular.io">Angular</a> JavaScript
|
|
||||||
framework. The application pages are generated based on an internal data set, and the other pages are simple
|
|
||||||
text components. Its bundling means that the initial page is small, and after the initial load, it runs
|
|
||||||
entirely in the browser or on a phone or tablet. Sites that reference external data sets would still need to
|
|
||||||
access the Internet to retrieve data, but this is much more efficient than having to download the entire page
|
|
||||||
every single click. (It's even <a href="https://github.com/bit-badger/bitbadger.solutions">open source</a> if
|
|
||||||
you want to see how we did it.)
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h2>WordPress Design, Customization, and Support</h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
We helped <a routerLink="/solutions/cassy-fiano" title="Cassy Fiano | Bit Badger Solutions">Cassy Fiano</a>
|
|
||||||
and <a routerLink="/solutions/dr-melissa-clouthier" title="Dr. Melissa Clouthier | Bit Badger Solutions">Dr.
|
|
||||||
Melissa Clouthier</a> both move their blogs from Blogspot to their own domains.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
We migrated <a routerLink="/solutions/liberty-pundits" title="Liberty Pundits">Liberty Pundits</a> from a
|
|
||||||
custom blog platform to WordPress, and set up and maintained their server, which routinely cleared 100,000
|
|
||||||
hits per day in its prime.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
For <a href="https://www.futilitycloset.com" title="Futility Closet">Futility Closet</a>
|
|
||||||
<small> (<a routerLink="/solutions/futility-closet" title="Futility Closet | Bit Badger Solutions">about</a>)</small>,
|
|
||||||
we moved their site from a shared hosting platform to its own <abbr title="Virtual Private Server">VPS</abbr>,
|
|
||||||
to enable it to handle its ever-increasing traffic.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<a routerLink="/solutions/tcms" title="TCMS | Bit Badger Solutions">TCMS</a> and
|
|
||||||
<a routerLink="/solutions/nsx" title="NSXapp | Bit Badger Solutions">NSXapp</a> both used WordPress as their
|
|
||||||
front end, which also provided a public web presence that the customers could update themselves.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
On <em><a href="https://blog.bitbadger.solutions" title="The Bit Badger Blog">The Bit Badger Blog</a></em> you can
|
|
||||||
browse the
|
|
||||||
<a href="https://blog.bitbadger.solutions/category/wordpress" title="WordPress | The Bit Badger Blog">WordPress</a>
|
|
||||||
category for information on plug-ins, and we have supported theme customizations for nearly all of the WordPress
|
|
||||||
sites linked on the sidebar/footer of the home page.
|
|
||||||
</p>
|
|
||||||
<p><br><a routerLink="/" title="Home">« Home</a></p>
|
|
||||||
</article>
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-information-publicizing',
|
|
||||||
templateUrl: './information-publicizing.component.html'
|
|
||||||
})
|
|
||||||
export class InformationPublicizingComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
<app-page-title title="Legacy Data Solutions"></app-page-title>
|
|
||||||
<article class="content auto">
|
|
||||||
<h1>Legacy Data Sharing</h1>
|
|
||||||
<p>
|
|
||||||
Our background in mainframe applications gives us a knowledgeable perspective on retrieving information from
|
|
||||||
older, “legacy” systems. This data can be migrated to a more modern relational or document database,
|
|
||||||
where a web application can retrieve the information; in some cases, the data can even be exposed as a web service
|
|
||||||
in place. These types of systems are often a great way for companies to expose their data to their customers,
|
|
||||||
without having to move their day-to-day system from its current environment. While we currently have no active
|
|
||||||
projects along these lines, our developers have done them in the past for other organizations; sadly, none can be
|
|
||||||
linked publicly.
|
|
||||||
</p>
|
|
||||||
<p><br><a routerLink="/" title="Home">« Home</a></p>
|
|
||||||
</article>
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-legacy-data',
|
|
||||||
templateUrl: './legacy-data.component.html'
|
|
||||||
})
|
|
||||||
export class LegacyDataComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
<app-page-title title="Process Automation Solutions"></app-page-title>
|
|
||||||
<article class="content auto">
|
|
||||||
<h1>Process Automation and User Engagement</h1>
|
|
||||||
<p>
|
|
||||||
Computers can be used to augment or automate nearly any process; could you think of generating bank statements,
|
|
||||||
processing mailing lists, or tracking orders without some form of automation? We develop web-based solutions to
|
|
||||||
automate <em>your</em> processes, ensuring that your business constraints are satisfied; these systems can run on
|
|
||||||
the Internet or your private network. For Internet-facing solutions, we engineer solutions that allow them to
|
|
||||||
interact with you securely, presented in an engaging manner. And, by “engagement,” we are not
|
|
||||||
describing intrusive page pop-ups and other <span class="strike">marketing gimmicks</span> web annoyances; we
|
|
||||||
determine an optimal user experience for <em>your</em> customers, and tailor the solution to work for both of you.
|
|
||||||
</p>
|
|
||||||
<p>Several of our solutions fit this description.</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<a routerLink="/solutions/virtual-prayer-room" title="Virtual Prayer Room | Bit Badger Solutions">Virtual
|
|
||||||
Prayer Room</a> helped the prayer ministry of
|
|
||||||
<a href="http://www.hoffmantown.org" title="Hoffmantown Church in Albuquerque, NM">Hoffmantown Church</a>
|
|
||||||
enable their prayer warriors to have access to requests wherever they are, even in their inbox once a day!
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<a routerLink="/solutions/tcms" title="TCMS | Bit Badger Solutions">TCMS</a> was an application that helped
|
|
||||||
organizations such as <a href="http://www.loveincabq.org">Love INC of South Albuquerque</a> connect people with
|
|
||||||
needs to people who can help fulfill those needs. TCMS sprung from the
|
|
||||||
<a href="https://nsx.archive.bitbadger.solutions" title="Not So Extreme Makeover: Community Edition (Archive)">Not
|
|
||||||
So Extreme Makeover: Community Edition</a> in Albuquerque, New Mexico during spring break 2008; we not only
|
|
||||||
developed the public presence, but a private system called
|
|
||||||
<a routerLink="/solutions/nsx" title="NSXapp | Bit Badger Solutions">NSXapp</a> that enabled the management of
|
|
||||||
the volunteers, families, and things for this massive effort.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
We continue to offer <a href="https://prayer.bitbadger.solutions" title="PrayerTracker">PrayerTracker</a>
|
|
||||||
<small> (<a routerLink="/solutions/prayer-tracker" title="PrayerTracker | Bit Badger Solutions">about</a>)</small>,
|
|
||||||
a free-to-use web application that helps Sunday School classes (or other small groups) generate a prayer
|
|
||||||
request list; it provides a central place for list management and continuity.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p><br><a routerLink="/" title="Home">« Home</a></p>
|
|
||||||
</article>
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-process-automation',
|
|
||||||
templateUrl: './process-automation.component.html'
|
|
||||||
})
|
|
||||||
export class ProcessAutomationComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
<app-page-title title="Web Services and API Solutions"></app-page-title>
|
|
||||||
<article class="content auto">
|
|
||||||
<h1>Web Services and APIs</h1>
|
|
||||||
<p>
|
|
||||||
A web service is a way of using the Internet to provide or accept information that makes sense to computers; this
|
|
||||||
allows other sites or applications to consume information from, or provide information to, your service. This
|
|
||||||
enables communication between applications, without having to establish any communication channels other than the
|
|
||||||
ones that web browsers already use. It isn't the best fit for every application, but when it is useful, it is
|
|
||||||
<em>very</em> useful.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
An <abbr title="Application Programming Interface">API</abbr> can be a synonym for a web service, but it can also
|
|
||||||
be a generally accessible way of providing data. For example, Twitter has a public API, which other applications
|
|
||||||
can use to display tweets on their site.
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<a routerLink="/solutions/photography-by-michelle" title="Photography by Michelle | Bit Badger Solutions">Photography
|
|
||||||
by Michelle</a> had a private web API that a desktop application utilized to create the online proof sets right
|
|
||||||
from the computer where the images resided.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
We
|
|
||||||
<a href="https://blog.bitbadger.solutions/2010/4040-web-service.html" title="40/40 Web Service | The Bit Badger Blog">wrote
|
|
||||||
a service</a> for the 2010
|
|
||||||
<a href="http://erlc.com/4040/" title="40/40 Prayer Vigil | Ethics and Religious Liberty Commission of the Southern Baptist Convention">40/40
|
|
||||||
Prayer Vigil</a>, which was utilized by several sites to display the current day's (or hour's) prayer focus, and
|
|
||||||
<a href="https://blog.bitbadger.solutions/2012/4040-web-service-for-2012.html" title="40/40 Web Service for 2012 | The Bit Badger Blog">wrote
|
|
||||||
one for 2012</a> as well. <em>(As the ERLC does not host these any more, this service is no longer active.)</em>
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<p>
|
|
||||||
<a href="https://prayerjournal.me">myPrayerJournal</a>
|
|
||||||
<small> (<a routerLink="/solutions/my-prayer-journal" title="myPrayerJournal | Bit Badger Solutions">about</a>)</small>
|
|
||||||
is a <abbr title="Single Page Application">SPA</abbr> which only downloads the structure of the site the first
|
|
||||||
time you go there, then utilizes a stateless API to access data from the browser.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p><br><a routerLink="/" title="Home">« Home</a></p>
|
|
||||||
</article>
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-web-services',
|
|
||||||
templateUrl: './web-services.component.html'
|
|
||||||
})
|
|
||||||
export class WebServicesComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
<app-page-title title="Why Bit Badger?"></app-page-title>
|
|
||||||
<article class="content auto">
|
|
||||||
<h1>Why “Bit Badger”?</h1>
|
|
||||||
<p>
|
|
||||||
A while back, our primary developer Daniel learned through genetic testing that he had one gene that was not right
|
|
||||||
(technically known as a genetic mutation). He is currently fine <em>(thank you for asking)</em>, but his co-workers
|
|
||||||
thought of another group of genetic mutants – the X-Men. They wanted to develop the mutant identity for him
|
|
||||||
in that style; since Wolverine is already taken, they wanted something similar, but based on a member of the weasel
|
|
||||||
family (for its normal private life and fierce tenacity, not its morals). They went through several different
|
|
||||||
options, but when “Bit Badger” was mentioned, it was the winner. The Bit Badger's mutant superpower is
|
|
||||||
the ability to shoot 1s and 0s out its nostrils!
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Daniel liked this moniker, and decided to run with it. He had been growing dissatisfied with the name “DJS
|
|
||||||
Consulting,” as he felt that name was passive. He enjoys taking problems and finding creative solutions for
|
|
||||||
them, making our computers work for us instead of the other way around. While he can't actually breathe out 1s and
|
|
||||||
0s, they do flow from his fingers (in groups of 8, of course).
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Do you have a problem that needs a solution? <a href="mailto:daniel@bitbadger.solutions">Sic the Bit Badger on
|
|
||||||
it</a>!
|
|
||||||
</p>
|
|
||||||
<p><br><a routerLink="/" title="Home">« Home</a></p>
|
|
||||||
</article>
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-why-bit-badger',
|
|
||||||
templateUrl: './why-bit-badger.component.html'
|
|
||||||
})
|
|
||||||
export class WhyBitBadgerComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
<app-page-title title="Welcome!"></app-page-title>
|
|
||||||
<div class="home">
|
|
||||||
<article class="content auto">
|
|
||||||
<p class="home-lead">Bit Badger Solutions develops the site you need to enable your success!</p>
|
|
||||||
<p>These solutions can take several different forms.</p>
|
|
||||||
<h2>Process Automation and User Engagement</h2>
|
|
||||||
<p>
|
|
||||||
Do you have a process that requires recording the same thing multiple times? Do you have information in different
|
|
||||||
places, but you need it all together? This solution is for you.
|
|
||||||
<a routerLink="/about/process-automation-solutions" title="Process Automation Solutions">Learn more about how
|
|
||||||
our solutions automate processes and engage users</a>.
|
|
||||||
</p>
|
|
||||||
<h2>Information Publicizing and Blogging</h2>
|
|
||||||
<p>
|
|
||||||
From its inception, the Web has been about information. Do you need to get information out about an upcoming
|
|
||||||
event? Are you wanting to start blogging, or breathe some fresh life into an existing blog? Those are but a few
|
|
||||||
of the problems that this solution solves.
|
|
||||||
<a routerLink="/about/information-publicizing-solutions" title="Information Publicizing Solutions">Find out more
|
|
||||||
about our information publicizing and blogging solutions</a> (including WordPress and statically-generated
|
|
||||||
sites).
|
|
||||||
</p>
|
|
||||||
<h2>Web Services and APIs</h2>
|
|
||||||
<p>
|
|
||||||
Do you have a need for multiple computers to talk to each other? Do you have an interesting data set that you want
|
|
||||||
to make available to the public? A web service or API may be just the solution for you.
|
|
||||||
<a routerLink="/about/web-services-solutions" title="Web Services and API Solutions">Learn about web services,
|
|
||||||
along with examples of current solutions</a>.
|
|
||||||
</p>
|
|
||||||
<h2>Legacy Data Sharing</h2>
|
|
||||||
<p>
|
|
||||||
Do you have data that's old — and by “old,” we aren’t talking “iPhone 6” old,
|
|
||||||
we’re talking “this data
|
|
||||||
<a href="https://en.wikipedia.org/wiki/Age_of_candidacy#United_States" title="Age of Candidacy (United States) | Wikipedia">could
|
|
||||||
run for President</a>” old? Just because the information is in an older “legacy” system
|
|
||||||
doesn’t mean it has to stay there.
|
|
||||||
<a routerLink="/about/legacy-data" title="Legacy Data Sharing Solutions">Learn how our solutions can help get
|
|
||||||
this data where you and your customers can access it more easily</a>.
|
|
||||||
</p>
|
|
||||||
<h2>Why Web-Based?</h2>
|
|
||||||
<p>Web-based solutions have many advantages:</p>
|
|
||||||
<ul>
|
|
||||||
<li><p>They can be used just on a local, private network (an intranet) or on the public Internet.</p></li>
|
|
||||||
<li><p>They are available to any device connected to the network.</p></li>
|
|
||||||
<li><p>They require no special software; every device has a browser - which you're using to read this!)</p></li>
|
|
||||||
<li><p>They can get your most critical needs met first, then evolved and improved over time.</p></li>
|
|
||||||
</ul>
|
|
||||||
<h2>What Is a “Bit Badger”?</h2>
|
|
||||||
<p>
|
|
||||||
<a routerLink="/about/why-bit-badger" title="Why Bit Badger?">Read the Bit Badger’s origin story</a>.
|
|
||||||
</p>
|
|
||||||
<h2>Solutions to Your Problems</h2>
|
|
||||||
<p>
|
|
||||||
We’d be happy to discuss your information technology needs, and which of our solutions are right for you.
|
|
||||||
Just <a href="mailto:daniel@bitbadger.solutions">e-mail us</a> and let us know what we can do for you! You can
|
|
||||||
also <a routerLink="/solutions" title="All Solutions">browse a complete list of our current and previous
|
|
||||||
solutions</a>.
|
|
||||||
</p>
|
|
||||||
</article>
|
|
||||||
<app-sidebar></app-sidebar>
|
|
||||||
</div>
|
|
@ -1,9 +0,0 @@
|
|||||||
@media all and (min-width: 80rem)
|
|
||||||
.home
|
|
||||||
display: flex
|
|
||||||
flex-flow: row
|
|
||||||
align-items: flex-start
|
|
||||||
justify-content: space-around
|
|
||||||
.home-lead
|
|
||||||
font-size: 1.3rem
|
|
||||||
text-align: center
|
|
@ -1,14 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-home',
|
|
||||||
templateUrl: './home.component.html',
|
|
||||||
styleUrls: ['./home.component.sass']
|
|
||||||
})
|
|
||||||
export class HomeComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
<footer>
|
|
||||||
A <strong><a routerLink="/">Bit Badger Solutions</a></strong> original design
|
|
||||||
</footer>
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user