Friendly component and prectise with signal
This commit is contained in:
parent
8bef46564e
commit
d7cd62183d
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +1,9 @@
|
||||||
{
|
{
|
||||||
"topBar":{
|
"topBar":{
|
||||||
"aboutMe" : "About me",
|
"aboutMe" : "About me",
|
||||||
"depreciationCalculator" :"Depreciation Calculator",
|
"depreciationCalculator" : "Depreciation Calculator",
|
||||||
"courses" : "Courses"
|
"courses" : "Courses",
|
||||||
|
"friendlyPages" : "Friendly Pages"
|
||||||
},
|
},
|
||||||
"asset-calculator": {
|
"asset-calculator": {
|
||||||
"depreciationCalculator" :"Depreciation Calculator",
|
"depreciationCalculator" :"Depreciation Calculator",
|
||||||
|
|
@ -26,6 +27,17 @@
|
||||||
"digressive" :"digressive",
|
"digressive" :"digressive",
|
||||||
"depreciationPlan" :"Depreciatin plan"
|
"depreciationPlan" :"Depreciatin plan"
|
||||||
},
|
},
|
||||||
|
"friendly_pages":{
|
||||||
|
"bodypainter_eu":
|
||||||
|
{
|
||||||
|
"short" : "Shall we paint someone?" ,
|
||||||
|
"href" : "https://bodypainter.eu?language=en",
|
||||||
|
"micro" : "Thumbnail of the bodypainter.eu website",
|
||||||
|
"description" : "Click to go to bodypainter.eu",
|
||||||
|
"title" : "Let's paint someone? bodypainter.eu",
|
||||||
|
"alt" : "bodypainter.eu"
|
||||||
|
}
|
||||||
|
},
|
||||||
"aboutMe":{
|
"aboutMe":{
|
||||||
"description": "<p>I am an experienced software engineer with over 20 years of experience in the IT industry.</p>\n<p>I specialize in Java and Angular technologies, as well as in the development and implementation of scalable web applications.</p>\n<p>I am an Oracle Cloud Infrastructure 2024 Generative AI Certified Professional and have prior qualifications in Oracle Cloud and Java programming.</p>\n<p>These skills support my implementation efforts modern cloud-based solutions and creating future-oriented applications.</p>\n<ul><b>Main technologies and tools:</b>\n<li>Programming languages: Java, JavaScript, C++</li> \n<li>Frameworks: Spring Boot, Angular, Thymeleaf</li>\n<li>Databases: Oracle, MSSQL, JavaDB</li>\n<li>Cloud environments: Oracle Cloud Infrastructure, Docker</li>\n<li>Other: HTML, CSS, Bootstrap, SVN, WildFly</li>\n</ul>"
|
"description": "<p>I am an experienced software engineer with over 20 years of experience in the IT industry.</p>\n<p>I specialize in Java and Angular technologies, as well as in the development and implementation of scalable web applications.</p>\n<p>I am an Oracle Cloud Infrastructure 2024 Generative AI Certified Professional and have prior qualifications in Oracle Cloud and Java programming.</p>\n<p>These skills support my implementation efforts modern cloud-based solutions and creating future-oriented applications.</p>\n<ul><b>Main technologies and tools:</b>\n<li>Programming languages: Java, JavaScript, C++</li> \n<li>Frameworks: Spring Boot, Angular, Thymeleaf</li>\n<li>Databases: Oracle, MSSQL, JavaDB</li>\n<li>Cloud environments: Oracle Cloud Infrastructure, Docker</li>\n<li>Other: HTML, CSS, Bootstrap, SVN, WildFly</li>\n</ul>"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
"topBar":{
|
"topBar":{
|
||||||
"aboutMe" : "O mnie",
|
"aboutMe" : "O mnie",
|
||||||
"depreciationCalculator" :"Kalkulator amortyzacyjny",
|
"depreciationCalculator" :"Kalkulator amortyzacyjny",
|
||||||
"courses" : "Kursy"
|
"courses" : "Kursy",
|
||||||
|
"friendlyPages" : "Zaprzyjaźnione strony"
|
||||||
},
|
},
|
||||||
"asset-calculator": {
|
"asset-calculator": {
|
||||||
"depreciationCalculator" :"Kalkulator amortyzacyjny",
|
"depreciationCalculator" :"Kalkulator amortyzacyjny",
|
||||||
|
|
@ -25,6 +26,17 @@
|
||||||
"linear" :"liniowa",
|
"linear" :"liniowa",
|
||||||
"digressive" :"dygresywna",
|
"digressive" :"dygresywna",
|
||||||
"depreciationPlan" :"Plan amortyzacji"
|
"depreciationPlan" :"Plan amortyzacji"
|
||||||
|
},
|
||||||
|
"friendly_pages":{
|
||||||
|
"bodypainter_eu":
|
||||||
|
{
|
||||||
|
"short" : "Pomalujemy kogoś ?" ,
|
||||||
|
"href" : "https://bodypainter.eu",
|
||||||
|
"micro" : "Miniaturka strony bodypainter.eu",
|
||||||
|
"description" : "Kliknij aby przejść na bodypainter.eu",
|
||||||
|
"title" : "Pomalujemy kogoś ? bodypainter.eu",
|
||||||
|
"alt" : "bodypainter.eu"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
"aboutMe":{
|
"aboutMe":{
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,30 @@
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
|
||||||
<div class="me-auto col-auto">
|
<div class="me-auto col-auto">
|
||||||
<a class="navbar-brand ms-2">
|
<a class="navbar-brand ms-2">
|
||||||
|
<a
|
||||||
|
class="navbar-brand ms-2"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
(click)="switchLanguage(translate.currentLang === 'pl' ? 'en' : 'pl')"
|
||||||
|
(keydown)="handleKeyDown($event)">
|
||||||
<img
|
<img
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="border border-dark"
|
class="border border-dark"
|
||||||
height="25"
|
height="25"
|
||||||
src="/flag-icons-main/flags/4x3/{{ translate.currentLang === 'pl' ? 'us' : 'pl' }}.svg"
|
src="/flag-icons-main/flags/4x3/{{ translate.currentLang === 'pl' ? 'us' : 'pl' }}.svg"
|
||||||
(click)="switchLanguage(translate.currentLang === 'pl' ? 'en' : 'pl')"
|
alt="Switch language"
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="container d-flex justify-content-between align-items-center">
|
<div class="container d-flex justify-content-between align-items-center">
|
||||||
<!-- Navbar links -->
|
<!-- Navbar links -->
|
||||||
<a class="navbar-brand" href="/about-me">{{ 'topBar.aboutMe' | translate }}</a>
|
<a class="navbar-brand" href="/about-me">{{ 'topBar.aboutMe' | translate }}</a>
|
||||||
<a class="navbar-brand" href="/asset-calculator">{{ 'topBar.depreciationCalculator' | translate }}</a>
|
<a class="navbar-brand" href="/asset-calculator">{{ 'topBar.depreciationCalculator' | translate }}</a>
|
||||||
<a class="navbar-brand" href="/quotes">{{ 'topBar.courses' | translate }}</a>
|
<a class="navbar-brand" href="/quotes">{{ 'topBar.courses' | translate }}</a>
|
||||||
|
<a class="navbar-brand" href="/friendly-pages">{{ 'topBar.friendlyPages' | translate }}</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<router-outlet />
|
<router-outlet />
|
||||||
`
|
|
||||||
|
|
@ -1,40 +1,61 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component, OnDestroy } from '@angular/core';
|
||||||
import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
import { TranslateService, TranslateModule} from "@ngx-translate/core";
|
import { TranslateService, TranslateModule} from "@ngx-translate/core";
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [ RouterOutlet, TranslateModule ],
|
imports: [ RouterOutlet, TranslateModule, ],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.css'
|
styleUrl: './app.component.css'
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent implements OnDestroy {
|
||||||
|
|
||||||
|
private langChangeSub: Subscription;
|
||||||
|
|
||||||
constructor( public translate: TranslateService ){
|
constructor( public translate: TranslateService ){
|
||||||
|
|
||||||
|
|
||||||
this.translate.addLangs(['pl', 'en']);
|
this.translate.addLangs(['pl', 'en']);
|
||||||
|
|
||||||
// Ustaw domyślny język aplikacji
|
|
||||||
this.translate.setDefaultLang('pl');
|
|
||||||
|
|
||||||
// Pobierz język przeglądarki i obetnij kod regionu // np. 'en' z 'en-US'
|
// Pobierz język przeglądarki i obetnij kod regionu // np. 'en' z 'en-US'
|
||||||
const browserLang = navigator.language .slice(0, 2);
|
const browserLang = navigator.language .slice(0, 2);
|
||||||
// Wyświetl w konsoli dla weryfikacji
|
// Wyświetl w konsoli dla weryfikacji
|
||||||
console.log('Język przeglądarki krótki:', browserLang);
|
console.log('Język przeglądarki krótki:', browserLang);
|
||||||
|
|
||||||
|
if( browserLang == 'en' || browserLang =='pl' ){
|
||||||
|
this.translate.setDefaultLang( browserLang );
|
||||||
|
}else{
|
||||||
|
this.translate.setDefaultLang('pl');
|
||||||
|
}
|
||||||
// Ustaw język pobrany z przeglądarki, jeśli jest obsługiwany
|
// Ustaw język pobrany z przeglądarki, jeśli jest obsługiwany
|
||||||
this.translate.use(browserLang.match(/en|pl/) ? browserLang : 'pl');
|
// this.translate.use(browserLang.match(/en|pl/) ? browserLang : 'pl');
|
||||||
|
|
||||||
|
this.langChangeSub = this.translate.onLangChange.subscribe((event) => {
|
||||||
|
console.log('Język ustawiany:', event.lang);
|
||||||
|
// localStorage.setItem('lang', selectedLang);
|
||||||
|
//this.loadAboutDescription();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ngOnDestroy() {
|
||||||
|
// Unsubscribing from the event when the component is destroyed to avoid memory leaks
|
||||||
|
if( this.langChangeSub ) {
|
||||||
|
console.log('unsubscribe');
|
||||||
|
this.langChangeSub.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
// app.component.ts
|
// app.component.ts
|
||||||
switchLanguage(language: string) {
|
switchLanguage(language: string) {
|
||||||
this.translate.use(language);
|
this.translate.use(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleKeyDown(event: KeyboardEvent): void {
|
||||||
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
|
this.switchLanguage( this.translate.currentLang === 'pl' ? 'en' : 'pl');
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
title = 'Strona';
|
title = 'Strona';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,15 @@ import { Routes } from '@angular/router';
|
||||||
import { DashboardComponent } from './components/dashboard/dashboard.component';
|
import { DashboardComponent } from './components/dashboard/dashboard.component';
|
||||||
import { AssetCalculatorComponent } from './asset-calculator/asset-calculator.component';
|
import { AssetCalculatorComponent } from './asset-calculator/asset-calculator.component';
|
||||||
import { AboutMeComponent } from './about-me/about-me.component';
|
import { AboutMeComponent } from './about-me/about-me.component';
|
||||||
import { ChatGPTComponent } from './chat-gpt/chat-gpt.component';
|
import { JobfinderComponent } from './jobfinder/jobfinder.component';
|
||||||
import {JobfinderComponent } from './jobfinder/jobfinder.component';
|
|
||||||
import { FixedAssetComponent } from './fixed-asset/fixed-asset.component';
|
import { FixedAssetComponent } from './fixed-asset/fixed-asset.component';
|
||||||
|
import { FriendlyPagesComponent } from './friendly-pages/friendly-pages.component';
|
||||||
|
|
||||||
|
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: "",
|
path: "",
|
||||||
title: "Środki trwałe",
|
title: "Sygnały",
|
||||||
component:AssetCalculatorComponent
|
component:AssetCalculatorComponent
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -37,6 +37,13 @@ export const routes: Routes = [
|
||||||
path: "fixed-asset",
|
path: "fixed-asset",
|
||||||
title:"Środki trwałe",
|
title:"Środki trwałe",
|
||||||
component: FixedAssetComponent
|
component: FixedAssetComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "friendly-pages",
|
||||||
|
title:"Zaprzyjaznione strony",
|
||||||
|
component: FriendlyPagesComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail-description {
|
||||||
|
margin-top: 10px; /* Odstęp między obrazem a opisem */
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<a href="{{'friendly-pages.bodypainter-eu-href' | translate }}">
|
||||||
|
{{'friendly-pages.bodypainter-eu' | translate }}
|
||||||
|
</a>
|
||||||
|
<!-- Template Angular -->
|
||||||
|
<a [href]="url" target="_blank">
|
||||||
|
<div class="thumbnail-container">
|
||||||
|
<img [src]="thumbnailUrl" alt="Miniaturka strony" />
|
||||||
|
<div class="thumbnail-description">
|
||||||
|
<p>{{ description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { FriendlyPagesComponent } from './friendly-pages.component';
|
||||||
|
|
||||||
|
describe('FriendlyPagesComponent', () => {
|
||||||
|
let component: FriendlyPagesComponent;
|
||||||
|
let fixture: ComponentFixture<FriendlyPagesComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [FriendlyPagesComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(FriendlyPagesComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import {TranslateModule} from "@ngx-translate/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-friendly-pages',
|
||||||
|
standalone: true,
|
||||||
|
imports: [TranslateModule],
|
||||||
|
template:`
|
||||||
|
<div class="container">
|
||||||
|
<div class="row row-cols-1 row-cols-md-3 g-4">
|
||||||
|
<div class="col">
|
||||||
|
<a href="{{ 'friendly_pages.bodypainter_eu.href' | translate }}" target="_blank" class="text-decoration-none">
|
||||||
|
<div class="card h-100">
|
||||||
|
<img
|
||||||
|
src="https://bodypainter.eu/zaklik-public-images/main/about-me.jpg"
|
||||||
|
class="card-img-top"
|
||||||
|
alt="{{'friendly_pages.bodypainter_eu.alt'| translate }}"
|
||||||
|
/>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-title text-center h2">{{ 'friendly_pages.bodypainter_eu.title' | translate }}</div>
|
||||||
|
<p class="card-text text-center">
|
||||||
|
<I>{{ 'friendly_pages.bodypainter_eu.description' | translate }}</I>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<!-- Dodaj więcej kolumn z kartami w podobnym stylu -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
`,
|
||||||
|
styleUrl: './friendly-pages.component.css'
|
||||||
|
})
|
||||||
|
export class FriendlyPagesComponent {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<p>signal-counter works!</p>
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SignalCounterComponent } from './signal-counter.component';
|
||||||
|
|
||||||
|
describe('SignalCounterComponent', () => {
|
||||||
|
let component: SignalCounterComponent;
|
||||||
|
let fixture: ComponentFixture<SignalCounterComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [SignalCounterComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(SignalCounterComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { Component, computed, signal } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-signal-counter',
|
||||||
|
standalone: true,
|
||||||
|
imports: [],
|
||||||
|
template:
|
||||||
|
`
|
||||||
|
<h1>Current value of the counter {{counter()}}</h1>
|
||||||
|
|
||||||
|
<h3>10x counter: {{derivedCounter()}}</h3>
|
||||||
|
|
||||||
|
<button (click)="increment()">Increment</button>
|
||||||
|
`,
|
||||||
|
styleUrl: './signal-counter.component.css'
|
||||||
|
})
|
||||||
|
export class SignalCounterComponent {
|
||||||
|
counter = signal( 0 );
|
||||||
|
derivedCounter = computed(() => {
|
||||||
|
return this.counter() * 10;
|
||||||
|
})
|
||||||
|
increment() {
|
||||||
|
console.log(`Incrementing counter...`+this.counter())
|
||||||
|
this.counter.set( this.counter() + 1);
|
||||||
|
console.log(`Now counter...`+this.counter())
|
||||||
|
this.counter.update(counter => counter + 1);
|
||||||
|
console.log(`Updating counter to ...`+this.counter())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue