From 7dc0c31be1669a4abc628c0f385789cf854a9e2e Mon Sep 17 00:00:00 2001 From: mastah Date: Sun, 25 Jan 2026 23:19:53 +0100 Subject: [PATCH] Added ability to set input age for pesel generator. No additional checks implemented - min < max or starting age of 1800. Someday... --- src/app/app.module.ts | 24 +++--- src/app/components/pesel/pesel.component.html | 23 ++++-- src/app/components/pesel/pesel.component.ts | 8 +- src/app/service/pesel.service.ts | 73 +++++++++++++------ src/styles.scss | 41 ++++++++++- 5 files changed, 123 insertions(+), 46 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5e2992b..86d90dc 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,10 +2,8 @@ import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './components/app/app.component'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatInputModule } from '@angular/material/input'; import { MatIconModule } from '@angular/material/icon'; -import { MatGridListModule } from '@angular/material/grid-list'; import { ClipboardModule } from '@angular/cdk/clipboard'; import { MatSnackBarModule} from '@angular/material/snack-bar'; import { TranslatePipe } from './translate-pipe'; @@ -13,6 +11,7 @@ import { PeselComponent } from './components/pesel/pesel.component'; import { NipComponent } from './components/nip/nip.component'; import { RegonComponent } from './components/regon/regon.component'; import { IbanComponent } from './components/iban/iban.component'; +import {NgOptimizedImage} from "@angular/common"; @NgModule({ declarations: [ @@ -23,17 +22,16 @@ import { IbanComponent } from './components/iban/iban.component'; RegonComponent, IbanComponent ], - imports: [ - BrowserModule, - FormsModule, - BrowserAnimationsModule, - MatInputModule, - MatIconModule, - MatGridListModule, - ClipboardModule, - MatSnackBarModule, - ReactiveFormsModule, - ], + imports: [ + BrowserModule, + FormsModule, + MatInputModule, + MatIconModule, + ClipboardModule, + MatSnackBarModule, + ReactiveFormsModule, + NgOptimizedImage, + ], providers: [TranslatePipe], bootstrap: [AppComponent] }) diff --git a/src/app/components/pesel/pesel.component.html b/src/app/components/pesel/pesel.component.html index 2b330f6..d116e07 100644 --- a/src/app/components/pesel/pesel.component.html +++ b/src/app/components/pesel/pesel.component.html @@ -2,18 +2,27 @@
PESEL
- Czy generować męskie numery PESEL + +
-
+ +
+ Czy generować męskie numery PESEL
- Czy generować żeńskie numery PESEL + Czy generować żeńskie numery PESEL
- +
- Generuj numer PESEL - Skopiuj numer PESEL do schowka - Definicja numeru PESEL na Wikipedii + Generuj numer PESEL + Skopiuj numer PESEL do schowka + Definicja numeru PESEL na Wikipedii
- \ No newline at end of file + diff --git a/src/app/components/pesel/pesel.component.ts b/src/app/components/pesel/pesel.component.ts index c0eb5f5..198780e 100644 --- a/src/app/components/pesel/pesel.component.ts +++ b/src/app/components/pesel/pesel.component.ts @@ -14,6 +14,8 @@ export class PeselComponent implements OnInit { public generateMale: boolean; public generateFemale: boolean; + public minAge: number; + public maxAge: number; constructor(private peselService: PeselService, private clipboardService: ClipboardService) { this.valueField = new FormControl('pesel'); @@ -21,6 +23,8 @@ export class PeselComponent implements OnInit { this.generateMale = true; this.generateFemale = true; + this.minAge = 18; + this.maxAge = 100; } ngOnInit(): void { @@ -28,11 +32,11 @@ export class PeselComponent implements OnInit { } generate(): void { - if (this.generateMale === false && this.generateFemale === false) { + if (!this.generateMale && !this.generateFemale) { return; } - this.valueField.setValue(this.peselService.generatePesel(this.generateMale, this.generateFemale)); + this.valueField.setValue(this.peselService.generatePesel(this.generateMale, this.generateFemale, this.minAge, this.maxAge)); } toggleMale(): void { diff --git a/src/app/service/pesel.service.ts b/src/app/service/pesel.service.ts index 200b272..9e65e65 100644 --- a/src/app/service/pesel.service.ts +++ b/src/app/service/pesel.service.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; import { CommonService } from './common.service'; -import { endOfMonth } from 'date-fns' +import {addDays, addYears, differenceInDays, endOfMonth} from 'date-fns' import { ValidationErrors } from '@angular/forms'; -import { concat } from 'rxjs'; @Injectable({ @@ -10,30 +9,45 @@ import { concat } from 'rxjs'; }) export class PeselService { // wagi kolejnych cyfr numeru PESEL - private readonly peselWeights: number[] = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]; + private static readonly peselWeights: number[] = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]; - private readonly maleDigits: number[] = [1, 3, 5, 7, 9]; + private static readonly maleDigits: number[] = [1, 3, 5, 7, 9]; - private readonly femaleDigits: number[] = [0, 2, 4, 6, 8]; + private static readonly femaleDigits: number[] = [0, 2, 4, 6, 8]; constructor(private common: CommonService) { } - public generatePesel(male: boolean, female: boolean): string { + public generatePesel(male: boolean, female: boolean, minAge: number, maxAge: number): string { + console.log('Generating PESEL female: ', female, ', male: ', male, ' with age range:', minAge, 'to', maxAge); + console.log('Current date:', new Date()) + + // ustalenie granicznych dat + const startDate = addYears(new Date(), -maxAge); + const endDate = addYears(new Date(), -minAge); + + // wyliczenie roznicy w dniach i jej dolanie do daty startowej + const difference = differenceInDays(endDate, startDate); + console.log("Difference in days: ", difference) + + const finalDate = addDays(startDate, this.common.getRandomInt(0, difference)); + + console.log('Final date:', finalDate); + // losowanie pierwszych 10 cyfr - const year: number = this.common.getRandomInt(0, 99); - const month: number = this.common.getRandomInt(1, 12); - const endDayOfMonth: number = endOfMonth(new Date(year, month - 1)).getDate(); - const day: number = this.common.getRandomInt(1, endDayOfMonth); + const fullYear: number = finalDate.getFullYear(); + const year: number = fullYear % 100; + const month: number = this.encodePeselMonth(finalDate.getMonth() + 1, fullYear); + const day: number = finalDate.getDate(); const rest: number = this.common.getRandomInt(0, 999); - const sexDigits: number[] = [... male ? this.maleDigits : [], ...female ? this.femaleDigits : []]; + const sexDigits: number[] = [... male ? PeselService.maleDigits : [], ...female ? PeselService.femaleDigits : []]; - const sexDigitIndex: number = this.common.getRandomInt(0, sexDigits.length - 1); - const sexDigit = sexDigits[sexDigitIndex]; + const sexDigitIndex: number = this.common.getRandomInt(0, sexDigits.length - 1) + const sexDigit = sexDigits[sexDigitIndex] // wyliczenie cyfry kontrolnej const peselWithoutControlDigit: string = this.common.pad(year, 2) + this.common.pad(month, 2) + this.common.pad(day, 2) + this.common.pad(rest, 3) + this.common.pad(sexDigit, 1); - const controlDigit: number = this.common.calculateControlDigit(peselWithoutControlDigit, this.peselWeights, this.lastStepFunction); + const controlDigit: number = this.common.calculateControlDigit(peselWithoutControlDigit, PeselService.peselWeights, this.lastStepFunction); // ostateczna konkatenacja return peselWithoutControlDigit + controlDigit; @@ -75,8 +89,8 @@ export class PeselService { /** * Walidacja numeru PESEL przy użyciu wyrażeń regularnych - * @param pesel - * @returns + * @param pesel + * @returns */ private validatePeselRegExp(pesel: string): boolean { return CommonService.numericRegExp.test(pesel); @@ -84,10 +98,10 @@ export class PeselService { /** * Pelna walidacja numeru PESEL: regexpem i weryfikacja cyfry kontrolnej - * @returns + * @returns */ private validatePeselControlDigit(pesel: string): boolean { - return this.common.validateControlDigit(pesel, this.peselWeights, this.lastStepFunction); + return this.common.validateControlDigit(pesel, PeselService.peselWeights, this.lastStepFunction); } /** @@ -97,9 +111,9 @@ export class PeselService { * 2000-2099 - miesiąc od 21 * 2100-2199 - miesiąc od 41 * 2200-2299 - miesiąc od 61 - * - * @param pesel - * @returns + * + * @param pesel + * @returns */ private validatePeselMonth(pesel: string): boolean { const month: number = parseInt(pesel.substring(2, 4), 10); @@ -159,6 +173,23 @@ export class PeselService { } } + private encodePeselMonth(month: number, year: number): number { + if (year >= 1800 && year <= 1899) { + return month + 80; + } + if (year >= 2000 && year <= 2099) { + return month + 20; + } + if (year >= 2100 && year <= 2199) { + return month + 40; + } + if (year >= 2200 && year <= 2299) { + return month + 60; + } + + return month; + } + private lastStepFunction(sum: number): number { sum = sum % 10; diff --git a/src/styles.scss b/src/styles.scss index 06b8e7d..987429e 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -56,7 +56,7 @@ body { padding: .2em; width: 25px; height: 25px; - + &:hover { background: rgba( 0, 0, 0, 0.30 ); } @@ -124,7 +124,7 @@ body { input[type="text"] { margin-top: 1em; width: 210px; - min-width: 0px; + min-width: 0; flex-grow: 1; flex-shrink: 1; padding: 0 0.7em; @@ -147,6 +147,41 @@ input[type="text"] { } } +input[type="number"] { + -moz-appearance:textfield; /* Firefox */ + margin: auto 0; + width: 37px; + min-width: 0; + flex-grow: 1; + flex-shrink: 1; + padding: 0 0.1em; + letter-spacing: 1px; + font-size: 0.8em; + height: 1.5em; + color: white; + + background: rgba(255, 255, 255, 0.15); + box-shadow: 0 8px 32px 0 rgba( 0, 38, 135, 0.37 ); + border-radius: 3px; + border: 1px solid rgba( 255, 255, 255, 0.20 ); +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + display: none; + -webkit-appearance: none; + margin: 0; +} + +.titleBarText { + width: 20px; + color: white; + text-align: center; + font-weight: bold; + letter-spacing: 2px; + margin-top: 10px; +} + img { cursor: pointer; filter: invert(100%); @@ -156,4 +191,4 @@ img { box-shadow: 0 8px 32px 0 rgba(255, 217, 120, 0.37); border-radius: 3px; border: 1px solid rgba(0, 0, 0, 0.10); -} \ No newline at end of file +}