Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .docker/production/Dockerfile.gha
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ ENV BUNDLER_VERSION=$BUNDLER_VERSION

# Only install what's needed that isn't in the base image
# https://github.com/docker-library/ruby/blob/master/2.7/slim-buster/Dockerfile
RUN apt-get update \
# Buster is EOL; point apt sources to the Debian archive and disable
# Release file validity checks so updates/installations work.
RUN sed -i \
-e 's|deb.debian.org/debian|archive.debian.org/debian|g' \
-e 's|security.debian.org/debian-security|archive.debian.org/debian-security|g' \
/etc/apt/sources.list \
&& apt-get -o Acquire::Check-Valid-Until=false update \
&& apt-get -yq dist-upgrade \
&& apt-get install -y \
fontconfig \
Expand Down
1 change: 1 addition & 0 deletions clients/html/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24.6.0
4 changes: 4 additions & 0 deletions clients/html/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
engine-strict=true
save-exact=true
update-notifier=false
fund=false
105 changes: 105 additions & 0 deletions clients/html/FILE_REPLACEMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
### File replacements by Angular build configuration

This note summarizes current file replacements defined in `angular.json` and the simplified approach using a centralized brand config.

#### Current simplified replacements

- **me**
- `src/app/brand.config.ts` → `src/app/brand.config.me.ts`
- **ma** (default)
- `src/app/brand.config.ts` → `src/app/brand.config.ma.ts`
- **dc**
- `src/app/brand.config.ts` → `src/app/brand.config.dc.ts`
- **me-production**
- `src/environments/environment.ts` → `src/environments/environment.prod.ts`
- `src/app/brand.config.ts` → `src/app/brand.config.me.ts`
- **ma-production**
- `src/environments/environment.ts` → `src/environments/environment.prod.ts`
- `src/app/brand.config.ts` → `src/app/brand.config.ma.ts`
- **dc-production**
- `src/environments/environment.ts` → `src/environments/environment.prod.ts`
- `src/app/brand.config.ts` → `src/app/brand.config.dc.ts`

#### Using configuration flags

Build commands select replacements via `--configuration`:

- `ng serve --configuration=me`
- `ng build --configuration=me`
- `ng serve --configuration=dc`
- `ng build --configuration=me-production`
- `ng build --configuration=dc-production`

#### Brand configuration files

Each brand has its own config file that exports the same `BRAND_CONFIG` constant:

**`src/app/brand.config.ts`** (default - MA)

```typescript
export const BRAND_CONFIG: BrandConfig = {
logoPath: 'assets/images/mhc_logo.svg',
faviconPath: 'assets/images/favicon.png',
rosterTemplatePath: 'assets/roster_upload_template.xlsx',
zipCodeDataPath: 'data/zipCode.json',
};
```

**`src/app/brand.config.me.ts`** (Maine)

```typescript
export const BRAND_CONFIG: BrandConfig = {
logoPath: 'assets/images/logo_me.svg',
faviconPath: 'assets/images/favicon_me.png',
rosterTemplatePath: 'assets/roster_upload_template_me.xlsx',
zipCodeDataPath: 'data/zipCodeME.json',
};
```

**`src/app/brand.config.dc.ts`** (District of Columbia)

```typescript
export const BRAND_CONFIG: BrandConfig = {
logoPath: 'assets/images/mhc_logo.svg', // Keep default for now
faviconPath: 'assets/images/favicon.png', // Keep default for now
rosterTemplatePath: 'assets/roster_upload_template.xlsx', // Keep default for now
zipCodeDataPath: 'data/zipCode.json', // Keep default for now
};
```

#### Implementation

Components now reference `BRAND_CONFIG` instead of hardcoded paths:

- `HeaderComponent` uses `BRAND_CONFIG.logoPath`
- `EmployerDetailsComponent` exposes `brand = BRAND_CONFIG`
- Template binds roster template link to `brand.rosterTemplatePath`

#### Benefits of this approach

- **Single file replacement**: Only swap `brand.config.ts` per brand
- **No code changes needed**: Components automatically use the correct paths
- **Easy maintenance**: Update paths in one place per brand
- **Production builds**: Combine brand config + environment swap
- **Future expansion**: Add new brand-specific assets by updating config files

#### Example npm scripts

```json
{
"scripts": {
"start:me": "ng serve --configuration=me",
"build:me": "ng build --configuration=me",
"build:me:prod": "ng build --configuration=me-production",
"start:dc": "ng serve --configuration=dc",
"build:dc:prod": "ng build --configuration=dc-production"
}
}
```

#### Next steps

1. Add brand-specific assets (logos, favicons, templates, zip code data)
2. Update brand config files with correct paths
3. Test builds with `--configuration` flags
4. Consider adding brand-specific SCSS variables for theming
10 changes: 7 additions & 3 deletions clients/html/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
},
{
"replace": "src/app/brand.config.ts",
"with": "src/app/brand.config.me.ts"
}
],
"optimization": true,
Expand All @@ -135,7 +139,7 @@
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"builder": "@angular/build:dev-server",
"options": {
"browserTarget": "quoting-tool:build"
},
Expand All @@ -155,13 +159,13 @@
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"builder": "@angular/build:extract-i18n",
"options": {
"browserTarget": "quoting-tool:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular/build:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
Expand Down
9 changes: 9 additions & 0 deletions clients/html/src/app/brand.config.dc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { BrandConfig } from './brand.types';

export const BRAND_CONFIG: BrandConfig = {
// DC (District of Columbia) brand configuration
logoPath: 'assets/images/mhc_logo.svg', // Keep default logo for now
faviconPath: 'assets/images/favicon.png', // Keep default favicon for now
rosterTemplatePath: 'assets/roster_upload_template.xlsx', // Keep default template for now
zipCodeDataPath: 'data/zipCode.json', // Keep default zip codes for now
};
9 changes: 9 additions & 0 deletions clients/html/src/app/brand.config.ma.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { BrandConfig } from './brand.types';

export const BRAND_CONFIG: BrandConfig = {
// MA (Maine) brand configuration - default
logoPath: 'assets/images/mhc_logo.svg',
faviconPath: 'assets/images/favicon.png',
rosterTemplatePath: 'assets/roster_upload_template.xlsx',
zipCodeDataPath: 'data/zipCode.json',
};
9 changes: 9 additions & 0 deletions clients/html/src/app/brand.config.me.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { BrandConfig } from './brand.types';

export const BRAND_CONFIG: BrandConfig = {
// ME (Maine) brand configuration
logoPath: 'assets/images/logo_me.svg',
faviconPath: 'assets/images/favicon_me.png',
rosterTemplatePath: 'assets/roster_upload_template_me.xlsx',
zipCodeDataPath: 'data/zipCodeME.json',
};
9 changes: 9 additions & 0 deletions clients/html/src/app/brand.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { BrandConfig } from './brand.types';

export const BRAND_CONFIG: BrandConfig = {
// Default brand: MA (Maine)
logoPath: 'assets/images/mhc_logo.svg',
faviconPath: 'assets/images/favicon.png',
rosterTemplatePath: 'assets/roster_upload_template.xlsx',
zipCodeDataPath: 'data/zipCode.json',
};
6 changes: 6 additions & 0 deletions clients/html/src/app/brand.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface BrandConfig {
logoPath: string;
faviconPath: string;
rosterTemplatePath: string;
zipCodeDataPath: string;
}
Binary file added clients/html/src/assets/images/favicon_me.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 64 additions & 0 deletions clients/html/src/assets/scss/branding/ma/client-styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// MA (Maine) Brand Variables - Default
// $client-primary: #007bff;
// $client-bg-color: #007bff;
// $client-bg-color-lighten: lighten($client-bg-color, 5%);

// // Additional brand-specific variables
// $brand-primary: $client-primary;
// $brand-secondary: #6c757d;
// $brand-accent: #28a745;
// $brand-text: #212529;
// $brand-background: #ffffff;

// // Brand-specific overrides
// $logo-width: 126px;
// $logo-height: 40px;

/*Theme Colors*/

:root {
--white: #ffffff;
--black: #000000;

--gray: #6c757d;
--gray-light: #f8f9fa;
--gray-dark: #343a40;
--gray-100: #f1f1f1;
--gray-200: #e9ecef;
--gray-300: #dee2e6;
--gray-400: #ced4da;
--gray-500: #adb5bd;
--gray-600: #6c757d;
--gray-700: #495057;
--gray-800: #343a40;
--gray-900: #212529;

--main-color: #007bff;
--main-color-light: #0056b3;
--secondary-color: #6c757d;
--secondary-color-light: #5a6268;
--destructive-color: #a00723;
--success-color: #28a745;

--background-color: #ffffff;
--border-color: var(--gray-200);

--link-color: #0036cb;

--text-light: var(--white);
--text-dark: #212529;

--shadow-color: var(--gray-200);
--shadow-black-10: rgba(0, 0, 0, 0.12);
--shadow-black-20: rgba(0, 0, 0, 0.24);
}

.nav {
--bs-nav-link-color: var(--secondary-color) !important;
--bs-nav-link-hover-color: var(--main-color);
}

/* MA BRAND SPECIFIC STYLES */
body {
background-color: var(--background-color) !important;
}
45 changes: 45 additions & 0 deletions clients/html/src/assets/scss/client-styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* Default Client Styles - Used when no specific brand configuration is specified */

/*Theme Colors*/

:root {
--white: #ffffff;
--black: #000000;

--gray: #6c757d;
--gray-light: #f8f9fa;
--gray-dark: #343a40;
--gray-100: #f1f1f1;
--gray-200: #e9ecef;
--gray-300: #dee2e6;
--gray-400: #ced4da;
--gray-500: #adb5bd;
--gray-600: #6c757d;
--gray-700: #495057;
--gray-800: #343a40;
--gray-900: #212529;

--main-color: #c56724;
--main-color-light: #dc8140;
--secondary-color: #0f5e82;
--secondary-color-light: #005e81;
--destructive-color: #a00723;
--success-color: #008000;

--background-color: #f2efef;
--border-color: var(--gray-200);

--link-color: #0036cb;

--text-light: var(--white);
--text-dark: #3e5569;

--shadow-color: var(--gray-200);
--shadow-black-10: rgba(0, 0, 0, 0.12);
--shadow-black-20: rgba(0, 0, 0, 0.24);
}

.nav {
--bs-nav-link-color: var(--secondary-color) !important;
--bs-nav-link-hover-color: var(--main-color);
}
2 changes: 1 addition & 1 deletion clients/html/src/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = function(config) {
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
Expand Down