Add localization

Add pages
This commit is contained in:
Marc Fokkert
2024-05-29 21:07:46 +02:00
parent 416e6c96de
commit 4357d4f5c7
24 changed files with 423 additions and 93 deletions

View File

@@ -17,6 +17,7 @@
"build": { "build": {
"builder": "@angular-devkit/build-angular:application", "builder": "@angular-devkit/build-angular:application",
"options": { "options": {
"localize": true,
"outputPath": "dist/marc-en-tineke-2024", "outputPath": "dist/marc-en-tineke-2024",
"index": "src/index.html", "index": "src/index.html",
"browser": "src/main.ts", "browser": "src/main.ts",
@@ -100,6 +101,14 @@
"scripts": [] "scripts": []
} }
} }
},
"i18n": {
"sourceLocale": "nl-NL",
"locales": {
"en-US": {
"translation": "messages-en.json"
}
}
} }
} }
} }

13
messages-en.json Normal file
View File

@@ -0,0 +1,13 @@
{
"locale": "en-US",
"translations": {
"mailTitleWholeDay": "RSVP Trouwen 2024",
"mailTitleEvening": "RSVP Trouwen 2024 Evening",
"whenOptionCeremony": "Ceremony",
"whenOptionCake": "Cake & Bubbles",
"whenOptionDinner": "Dinner",
"whenOptionChurch": "Church Ceremony",
"whenOptionParty": "Feest",
"mailBody": "Glad to hear you are attending! Please provide answers to the following questions:\n\nI will attend with: X persons\nI will be attending (please remove the events you will not attend):\n{$PH}\nNotes and dietary requirements"
}
}

13
messages-nl.json Normal file
View File

@@ -0,0 +1,13 @@
{
"locale": "nl-NL",
"translations": {
"mailTitleWholeDay": "RSVP Trouwen 2024",
"mailTitleEvening": "RSVP Trouwen 2024 Avond",
"whenOptionCeremony": "Ceremonie",
"whenOptionCake": "Taart & Bubbels",
"whenOptionDinner": "Diner",
"whenOptionChurch": "Kerkdienst",
"whenOptionParty": "Feest",
"mailBody": "Fijn dat je komt! Geef hieronder antwoord op de volgende vragen:\n\nIk kom met: X personen\nIk ben er bij met (verwijder als je niet aanwezig bent):\n{$PH}\nVerdere opmerkingen/dieetwensen"
}
}

111
package-lock.json generated
View File

@@ -27,6 +27,7 @@
"@angular-devkit/build-angular": "^17.3.7", "@angular-devkit/build-angular": "^17.3.7",
"@angular/cli": "^17.3.7", "@angular/cli": "^17.3.7",
"@angular/compiler-cli": "^17.3.0", "@angular/compiler-cli": "^17.3.0",
"@angular/localize": "^17.3.9",
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"@types/jasmine": "~5.1.0", "@types/jasmine": "~5.1.0",
"@types/node": "^18.18.0", "@types/node": "^18.18.0",
@@ -463,6 +464,75 @@
"rxjs": "^6.5.3 || ^7.4.0" "rxjs": "^6.5.3 || ^7.4.0"
} }
}, },
"node_modules/@angular/localize": {
"version": "17.3.9",
"resolved": "https://registry.npmjs.org/@angular/localize/-/localize-17.3.9.tgz",
"integrity": "sha512-ECWWw6GoJh2laopHIf+QT4bDDpSWwQJk95SGPI5mQIEXZXw6w9ms05Sfb8KJTNRXs9kcotloIGK9YanFZxzK1g==",
"dev": true,
"dependencies": {
"@babel/core": "7.23.9",
"@types/babel__core": "7.20.5",
"fast-glob": "3.3.2",
"yargs": "^17.2.1"
},
"bin": {
"localize-extract": "tools/bundles/src/extract/cli.js",
"localize-migrate": "tools/bundles/src/migrate/cli.js",
"localize-translate": "tools/bundles/src/translate/cli.js"
},
"engines": {
"node": "^18.13.0 || >=20.9.0"
},
"peerDependencies": {
"@angular/compiler": "17.3.9",
"@angular/compiler-cli": "17.3.9"
}
},
"node_modules/@angular/localize/node_modules/@babel/core": {
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
"integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.23.5",
"@babel/generator": "^7.23.6",
"@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-module-transforms": "^7.23.3",
"@babel/helpers": "^7.23.9",
"@babel/parser": "^7.23.9",
"@babel/template": "^7.23.9",
"@babel/traverse": "^7.23.9",
"@babel/types": "^7.23.9",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"json5": "^2.2.3",
"semver": "^6.3.1"
},
"engines": {
"node": ">=6.9.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/babel"
}
},
"node_modules/@angular/localize/node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
"node_modules/@angular/localize/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@angular/platform-browser": { "node_modules/@angular/platform-browser": {
"version": "17.3.9", "version": "17.3.9",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.3.9.tgz", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.3.9.tgz",
@@ -3854,6 +3924,47 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
"integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.20.7",
"@babel/types": "^7.20.7",
"@types/babel__generator": "*",
"@types/babel__template": "*",
"@types/babel__traverse": "*"
}
},
"node_modules/@types/babel__generator": {
"version": "7.6.8",
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
"integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
"dev": true,
"dependencies": {
"@babel/types": "^7.0.0"
}
},
"node_modules/@types/babel__template": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
"integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
"node_modules/@types/babel__traverse": {
"version": "7.20.6",
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
"integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
"dev": true,
"dependencies": {
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/body-parser": { "node_modules/@types/body-parser": {
"version": "1.19.5", "version": "1.19.5",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",

View File

@@ -7,7 +7,8 @@
"build": "ng build", "build": "ng build",
"watch": "ng build --watch --configuration development", "watch": "ng build --watch --configuration development",
"test": "ng test", "test": "ng test",
"serve:ssr:marc-en-tineke-2024": "node dist/marc-en-tineke-2024/server/server.mjs" "serve:ssr:marc-en-tineke-2024": "node dist/marc-en-tineke-2024/server/server.mjs",
"i18n": "ng extract-i18n --format=json --out-file=messages-nl.json"
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
@@ -30,6 +31,7 @@
"@angular-devkit/build-angular": "^17.3.7", "@angular-devkit/build-angular": "^17.3.7",
"@angular/cli": "^17.3.7", "@angular/cli": "^17.3.7",
"@angular/compiler-cli": "^17.3.0", "@angular/compiler-cli": "^17.3.0",
"@angular/localize": "^17.3.9",
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"@types/jasmine": "~5.1.0", "@types/jasmine": "~5.1.0",
"@types/node": "^18.18.0", "@types/node": "^18.18.0",
@@ -41,4 +43,4 @@
"karma-jasmine-html-reporter": "~2.1.0", "karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.4.2" "typescript": "~5.4.2"
} }
} }

View File

@@ -1,32 +1 @@
<h1>TINEKE <span class="small">&</span> MARC</h1> <router-outlet></router-outlet>
<span class="subtitle">20 september 2024</span>
<div class="heart">
<app-heart></app-heart>
</div>
<section class="schedule">
<section class="item">
<h3>RSVP</h3>
<a>Voor 10 augustus</a>
</section>
<section class="item">
<h3>Laat ons weten of je komt!</h3>
<a href="mailto:marcentinekegaantrouwen@xz1.nl">Stuur een mail</a>
</section>
<section class="item">
<h3>Dieetwensen</h3>
<span>Laat het ons weten, dan kunnen we er rekening mee houden.</span>
</section>
<section class="item">
<h3>Stukjes/inzendingen</h3>
<span>Via de ceremoniemeester <a href="mailto:marcentinekegaantrouwen@xz1.nl">Lianne Fokkert</a></span>
</section>
<section class="item">
<h3>Cadeautip</h3>
<span>Envelop</span>
</section>
</section>

View File

@@ -1,55 +0,0 @@
@use "../styles/variables";
h1, {
font-size: 34px;
font-weight: bold;
.small {
font-family: "beautifully-delicious", serif;
font-size: 60px;
font-style: italic;
}
}
h1, .subtitle {
font-family: variables.$tan-moncheri;
text-align: center;
}
.heart {
text-align: center;
}
.subtitle {
display: block;
font-size: 22px;
}
h2, h3 {
font-weight: normal;
}
p, h2, h3, .schedule {
font-family: variables.$playfair-display;
}
.schedule {
margin-top: 16px;
text-align: center;
.item {
h3 {
margin-bottom: 0;
}
a {
color: black;
}
}
}
p {
margin-bottom :0;
}

View File

@@ -1,3 +1,21 @@
import { Routes } from '@angular/router'; import { Routes } from '@angular/router';
import {AppComponent} from "./app.component";
import {DirectionsPageComponent} from "./directions-page/directions-page.component";
import {LandingPageComponent} from "./landing-page/landing-page.component";
export const routes: Routes = []; export const routes: Routes = [
{
path: 'directions',
component: DirectionsPageComponent
},
{
path: '',
component: LandingPageComponent,
pathMatch: 'full'
},
{
path: '**',
redirectTo: ''
}
];

View File

@@ -0,0 +1 @@
<p>directions-page works!</p>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DirectionsPageComponent } from './directions-page.component';
describe('DirectionsPageComponent', () => {
let component: DirectionsPageComponent;
let fixture: ComponentFixture<DirectionsPageComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [DirectionsPageComponent]
})
.compileComponents();
fixture = TestBed.createComponent(DirectionsPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,12 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-directions-page',
standalone: true,
imports: [],
templateUrl: './directions-page.component.html',
styleUrl: './directions-page.component.scss'
})
export class DirectionsPageComponent {
}

View File

@@ -1,3 +1,11 @@
svg { svg {
height: 10px; height: 10px;
} }
:host {
margin-top: 24px;
margin-bottom: 24px;
display: flex;
justify-content: center;
}

View File

@@ -0,0 +1,36 @@
<h1 class="names">TINEKE <span class="small">&</span> MARC</h1>
<span class="invite-text">Nodigen jullie uit voor hun bruiloft op</span>
<h2 class="subtitle">20 september 2024</h2>
<section class="schedule">
<section class="item">
<h3>RSVP</h3>
<a>Voor 10 augustus</a>
</section>
<app-heart></app-heart>
<section class="item">
<h3>Laat ons weten of je komt!</h3>
<a [href]="getMailToLink()">Stuur een mail</a>
</section>
<app-heart></app-heart>
<section class="item">
<h3>Dieetwensen</h3>
<span>Laat het ons weten, dan kunnen we er rekening mee houden.</span>
</section>
<app-heart></app-heart>
<section class="item">
<h3>Stukjes/inzendingen</h3>
<span>Via de ceremoniemeester <a href="mailto:marcentinekegaantrouwen@xz1.nl">Lianne Fokkert</a></span>
</section>
<app-heart></app-heart>
<section class="item">
<h3>Cadeautip</h3>
<img class="envelope" src="assets/images/envelope.png" alt="Envelope" />
</section>
<app-heart></app-heart>
<section class="item">
<h3>Adressen</h3>
<a routerLink="directions">Klik</a>
</section>
</section>

View File

@@ -0,0 +1,81 @@
@use "../../styles/variables";
h1.names, {
font-size: 34px;
font-weight: bold;
display: flex;
justify-content: center;
.small {
font-family: "beautifully-delicious", serif;
font-size: 60px;
font-style: italic;
height: 48px;
line-height: 29px;
padding-left: 18px;
padding-right: 18px;
}
}
h1, .subtitle {
font-family: variables.$tan-moncheri;
text-align: center;
}
.subtitle {
display: block;
font-size: 24px;
margin-bottom: 60px;
}
.invite-text {
display: flex;
justify-content: center;
margin-top: -24px;
font-size: 16px;
}
h2, h3 {
font-weight: normal;
}
p, h2, h3, .schedule {
font-family: variables.$playfair-display;
}
.schedule {
margin-top: 16px;
text-align: center;
.item {
h3 {
margin-bottom: 0;
}
a {
color: rgb(48, 77, 42);;
&:hover {
color: black;
}
}
}
}
p {
margin-bottom :0;
}
img.envelope {
width: 64px;
margin-top: 8px;
}

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LandingPageComponent } from './landing-page.component';
describe('LandingPageComponent', () => {
let component: LandingPageComponent;
let fixture: ComponentFixture<LandingPageComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [LandingPageComponent]
})
.compileComponents();
fixture = TestBed.createComponent(LandingPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,54 @@
import {Component} from '@angular/core';
import {HeartComponent} from "../heart/heart.component";
import {RouterLink} from "@angular/router";
@Component({
selector: 'app-landing-page',
standalone: true,
imports: [
HeartComponent,
RouterLink
],
templateUrl: './landing-page.component.html',
styleUrl: './landing-page.component.scss'
})
export class LandingPageComponent {
title = 'marc-en-tineke-2024';
mailTitleWholeDay = $localize`:@@mailTitleWholeDay:RSVP Trouwen 2024`;
mailTitleEvening = $localize`:@@mailTitleEvening:RSVP Trouwen 2024 Avond`;
whenQuestionOptionsWholeDay = [
$localize`:@@whenOptionCeremony:Ceremonie`,
$localize`:@@whenOptionCake:Taart & Bubbels`,
$localize`:@@whenOptionDinner:Diner`,
$localize`:@@whenOptionChurch:Kerkdienst`,
$localize`:@@whenOptionParty:Feest`
]
whenQuestionOptionsEvening = [
$localize`:@@whenOptionChurch:Kerkdienst`,
$localize`:@@whenOptionParty:Feest`
]
mailBody = $localize`:@@mailBody:Wat fijn dat je ons laat weten of je er bij bent!%0D%0A
Ik kom met: %0D%0A
- X personen%0D%0A %0D%0A
Ik ben er bij met (verwijder als je niet aanwezig bent):
%0D%0A
${this.getWhenQuestions()}%0D%0A
%0D%0AVerdere opmerkingen/dieetwensen`
getWhenQuestions() {
return this.whenQuestionOptionsWholeDay.map(item => `- ${encodeURIComponent(item)}`).join('%0D%0A');
}
getMailToLink() {
return `mailto:marcentinekegaantrouwen@xz1.nl?subject=${this.mailTitleWholeDay}&body=${this.mailBody}`.replace('\n', '%0D%0A');
}
goToAddressesPage() {
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" clip-rule="evenodd" fill-rule="evenodd" image-rendering="optimizeQuality" preserveAspectRatio="xMidYMid meet" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" version="1.0" viewBox="-36.0 -34.0 313.0 233.0" zoomAndPan="magnify" style="fill: rgb(0, 0, 0);" original_string_length="553"><g id="__id128_s2nobdp0wg"><path d="M104 51c-21,-85 -140,-48 -93,37 7,13 74,87 95,111 17,-24 43,-46 72,-85 99,-133 -55,-144 -74,-63z"/></g></svg>

Before

Width:  |  Height:  |  Size: 538 B

View File

@@ -1,3 +1,5 @@
/// <reference types="@angular/localize" />
import { bootstrapApplication } from '@angular/platform-browser'; import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config'; import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component'; import { AppComponent } from './app/app.component';

View File

@@ -1,3 +1,7 @@
/* You can add global styles to this file, and also import other style files */ /* You can add global styles to this file, and also import other style files */
@import "./styles/fonts"; @import "./styles/fonts";
html {
color: rgb(48, 77, 42);
}

View File

@@ -1,2 +1,7 @@
$playfair-display: "playfair-display", serif; $playfair-display: "playfair-display", serif;
$tan-moncheri: "tan-moncheri", sans-serif; $tan-moncheri: "tan-moncheri", sans-serif;
$font-sizes: (
"h1": "96px;"
)

View File

@@ -4,7 +4,8 @@
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/app", "outDir": "./out-tsc/app",
"types": [ "types": [
"node" "node",
"@angular/localize"
] ]
}, },
"files": [ "files": [

View File

@@ -4,7 +4,8 @@
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/spec", "outDir": "./out-tsc/spec",
"types": [ "types": [
"jasmine" "jasmine",
"@angular/localize"
] ]
}, },
"include": [ "include": [