Compare commits
9 Commits
01376c3611
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e40130ec3 | |||
| b65ac0d370 | |||
| 728baae26b | |||
| 375ed63b5e | |||
| 7f485b3786 | |||
| 99a95adb84 | |||
| 10dd04dad7 | |||
| 10f9b77807 | |||
| a00aaef3c6 |
11
AI.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# AI Training Policy
|
||||
|
||||
This codebase is NOT intended for AI/ML training.
|
||||
Do not use this code for:
|
||||
|
||||
- AI model training
|
||||
- Code generation datasets
|
||||
- Machine learning purposes
|
||||
- Automated code suggestion systems
|
||||
|
||||
Permission is not granted for AI ingestion or training.
|
||||
70
README.md
@@ -1,59 +1,25 @@
|
||||
## 🚫 AI/ML Training Restrictions
|
||||
|
||||
**This code is NOT suitable for AI training purposes.**
|
||||
The code quality may contain security issues or anti-patterns.
|
||||
Do not include this repository in any AI/ML training datasets.
|
||||
|
||||
# AgendaWeb
|
||||
|
||||
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.9.
|
||||
🇪🇸
|
||||
Este sitio web es un remake de una de las lecciones en desarrollo web del curso "Desarrollo Web Completo con HTML5, CSS3, JS AJAX PHP y MySQL" por Juan Pablo De La Torre Valdez, con el objetivo de emplear intensivamente las herramientas nuevas y no tan nuevas que ofrece Angular. Adicionalmente el lado del backend esta desarrollado en Go con la finalidad de desarrollar competencias y expertise con este lenguaje.
|
||||
|
||||
## Development server
|
||||
Puedes ver el sitio original [aquí](https://agendaproject.epizy.com)
|
||||
Y el repositorio [acá](https://github.com/gabdlr/projects-AgendaWeb)
|
||||
El código del backend esta en este [repositorio](https://gitea.gabilandia.com/gabdlr/agenda-web-go)
|
||||
|
||||
To start a local development server, run:
|
||||
Que lo disfrutes!
|
||||
|
||||
```bash
|
||||
ng serve
|
||||
```
|
||||
🇺🇸
|
||||
This web site is a remake of on the lessons from a web development course "Desarrollo Web Completo con HTML5, CSS3, JS AJAX PHP y MySQL" by Juan Pablo De La Torre Valdez, with the intention of intensively using newer and not so new tools offered by Angular. Aditionally the backend side has been developed using Go with the goal of developing proficiency and expetise with this language.
|
||||
|
||||
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
|
||||
You can take a look a the original site [here](https://agendaproject.epizy.com)
|
||||
And it's repository [here](https://github.com/gabdlr/projects-AgendaWeb)
|
||||
The backend code is in this [repository](https://gitea.gabilandia.com/gabdlr/agenda-web-go)
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
||||
|
||||
```bash
|
||||
ng generate component component-name
|
||||
```
|
||||
|
||||
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
||||
|
||||
```bash
|
||||
ng generate --help
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To build the project run:
|
||||
|
||||
```bash
|
||||
ng build
|
||||
```
|
||||
|
||||
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
|
||||
|
||||
```bash
|
||||
ng test
|
||||
```
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
For end-to-end (e2e) testing, run:
|
||||
|
||||
```bash
|
||||
ng e2e
|
||||
```
|
||||
|
||||
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
||||
|
||||
## Additional Resources
|
||||
|
||||
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
||||
Enjoy!
|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 240 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 413 KiB |
|
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 17 KiB |
@@ -3,7 +3,8 @@
|
||||
"short_name": "Gabigenda",
|
||||
"display": "standalone",
|
||||
"scope": "./",
|
||||
"background_color": "#ff0000",
|
||||
"background_color": "#fefffa",
|
||||
"theme_color": "#9c0a45",
|
||||
"start_url": "./",
|
||||
"icons": [
|
||||
{
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
|
||||
<div class="fields">
|
||||
<app-form-field
|
||||
[errorsDictionary]="companyAndNameErrorsDictionary"
|
||||
[errorsDictionary]="companyAndNameErrorsDictionary()"
|
||||
formControlName="name"
|
||||
[label]="(languageManager.strings.name|upperfirst) + ':'"
|
||||
[placeholder]="languageManager.strings.contactsName|upperfirst"
|
||||
/>
|
||||
<app-form-field
|
||||
[errorsDictionary]="companyAndNameErrorsDictionary"
|
||||
[errorsDictionary]="companyAndNameErrorsDictionary()"
|
||||
formControlName="company"
|
||||
[label]="(languageManager.strings.company|upperfirst) + ':'"
|
||||
[placeholder]="languageManager.strings.contactsCompany|upperfirst"
|
||||
/>
|
||||
<app-form-field
|
||||
[errorsDictionary]="phoneErrorsDictionary"
|
||||
[errorsDictionary]="phoneErrorsDictionary()"
|
||||
formControlName="phone"
|
||||
[label]="(languageManager.strings.phone|upperfirst) +':'"
|
||||
[placeholder]="languageManager.strings.contactsPhone|upperfirst"
|
||||
|
||||
@@ -12,7 +12,10 @@ describe('ContactForm', () => {
|
||||
let languageManager: jasmine.SpyObj<LanguageManager>;
|
||||
|
||||
beforeEach(async () => {
|
||||
languageManager = jasmine.createSpyObj(LanguageManager.name, [], { strings: strings.en });
|
||||
languageManager = jasmine.createSpyObj(LanguageManager.name, [], {
|
||||
strings: strings.en,
|
||||
selectedLanguage$: () => 'en',
|
||||
});
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ContactForm],
|
||||
|
||||
@@ -26,6 +26,7 @@ export class ContactForm {
|
||||
protected phoneErrorsDictionary = new PhoneFieldErroresDictionary().getDictionary();
|
||||
|
||||
handleSubmit(contactForm: ContactFormValue) {
|
||||
if (this.form().invalid) return;
|
||||
if (contactForm.company === null || contactForm.name === null || contactForm.phone === null)
|
||||
return;
|
||||
const contact = new ContactDTO(
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div>
|
||||
@for(error of errorsDictionary()|keyvalue; track error.key) {
|
||||
@if(control.hasError(error.key) && isDirty){
|
||||
<p class="error-text">• {{error.value}}</p>
|
||||
<p class="error-text">• {{error.value|upperfirst}}</p>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { KeyValuePipe } from '@angular/common';
|
||||
import { Component, computed, input, Optional, Self, signal } from '@angular/core';
|
||||
import { ControlValueAccessor, NgControl, ReactiveFormsModule } from '@angular/forms';
|
||||
import { UpperfirstPipe } from '../../pipes/upperfirst-pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'app-form-field',
|
||||
imports: [ReactiveFormsModule, KeyValuePipe],
|
||||
imports: [ReactiveFormsModule, KeyValuePipe, UpperfirstPipe],
|
||||
templateUrl: './form-field.html',
|
||||
styleUrl: './form-field.scss',
|
||||
})
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { computed, inject, Signal, signal } from '@angular/core';
|
||||
import { Dictionary } from '../interfaces/dictionary.interface';
|
||||
import { LanguageManager } from '../services/language-manager';
|
||||
|
||||
export class NameAndCompanyFieldsErrorsDictionary implements Dictionary {
|
||||
private readonly languageManager = inject(LanguageManager);
|
||||
private readonly maxlen: string;
|
||||
private readonly required = this.languageManager.strings.errorMessageRequired;
|
||||
|
||||
constructor() {
|
||||
this.maxlen = this.languageManager.strings.errorMessageMaxLength(120);
|
||||
}
|
||||
|
||||
getDictionary(): { [key: string]: string } {
|
||||
const { maxlen, required } = this;
|
||||
return { maxlen, required };
|
||||
getDictionary(): Signal<{ [key: string]: string }> {
|
||||
return computed(
|
||||
() =>
|
||||
this.languageManager.selectedLanguage$() && {
|
||||
maxlen: this.languageManager.strings.errorMessageMaxLength(120),
|
||||
required: this.languageManager.strings.errorMessageRequired,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { computed, inject, Signal } from '@angular/core';
|
||||
import { Dictionary } from '../interfaces/dictionary.interface';
|
||||
import { LanguageManager } from '../services/language-manager';
|
||||
|
||||
export class PhoneFieldErroresDictionary implements Dictionary {
|
||||
languageManager = inject(LanguageManager);
|
||||
pattern = this.languageManager.strings.errorMessagePhonePattern;
|
||||
required = this.languageManager.strings.errorMessageRequired;
|
||||
|
||||
getDictionary(): { [key: string]: string } {
|
||||
const { required, pattern } = this;
|
||||
return { required, pattern };
|
||||
getDictionary(): Signal<{ [key: string]: string }> {
|
||||
return computed(
|
||||
() =>
|
||||
this.languageManager.selectedLanguage$() && {
|
||||
pattern: this.languageManager.strings.errorMessagePhonePattern,
|
||||
required: this.languageManager.strings.errorMessageRequired,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Signal } from '@angular/core';
|
||||
|
||||
export interface Dictionary {
|
||||
getDictionary(): { [key: string]: string };
|
||||
getDictionary(): Signal<{ [key: string]: string }>;
|
||||
}
|
||||
|
||||
@@ -21,12 +21,15 @@ describe('Edit', () => {
|
||||
let CONTACT_MOCK: ContactDTO;
|
||||
|
||||
beforeEach(async () => {
|
||||
CONTACT_MOCK = new ContactDTO(1, 'mock', 'mock', 'mock');
|
||||
CONTACT_MOCK = new ContactDTO(1, 'mock', 'mock', '123456789012');
|
||||
activatedRoute = jasmine.createSpyObj(ActivatedRoute.name, [], {
|
||||
data: of({ contact: CONTACT_MOCK }),
|
||||
});
|
||||
contactService = jasmine.createSpyObj(ContactService.name, ['update']);
|
||||
languageManager = jasmine.createSpyObj(LanguageManager.name, [], { strings: strings.en });
|
||||
languageManager = jasmine.createSpyObj(LanguageManager.name, [], {
|
||||
strings: strings.en,
|
||||
selectedLanguage$: () => 'en',
|
||||
});
|
||||
router = jasmine.createSpyObj(Router.name, ['navigate']);
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
|
||||
@@ -15,15 +15,15 @@ export const strings = Object.freeze({
|
||||
editContact: 'edit contact',
|
||||
editContactSuccessNotification: 'contact edited successfully',
|
||||
editTheContact: 'edit the contact',
|
||||
errorMessageMaxLength: (maxLen: number) => `Must be ${maxLen} characters or fewer.`,
|
||||
errorMessagePhonePattern: `Valid format: + (optional) plus 12 to 15 digits`,
|
||||
errorMessageRequired: 'This field is required.',
|
||||
errorNotification: 'Oops, there was an error',
|
||||
errorMessageMaxLength: (maxLen: number) => `must be ${maxLen} characters or fewer`,
|
||||
errorMessagePhonePattern: `valid format: + (optional) plus 12 to 15 digits`,
|
||||
errorMessageRequired: 'this field is required',
|
||||
errorNotification: 'oops, there was an error',
|
||||
goBack: 'go back',
|
||||
name: 'name',
|
||||
phone: 'phone',
|
||||
save: 'save',
|
||||
searchContactPlaceholder: 'Search contact...',
|
||||
searchContactPlaceholder: 'search contact...',
|
||||
},
|
||||
es: {
|
||||
actions: 'acciones',
|
||||
@@ -41,9 +41,9 @@ export const strings = Object.freeze({
|
||||
editContact: 'editar contacto',
|
||||
editContactSuccessNotification: 'contacto editado correctamente',
|
||||
editTheContact: 'edite el contacto. ',
|
||||
errorMessageMaxLength: (maxLen: number) => `Debe contener ${maxLen} caracteres or menos.`,
|
||||
errorMessagePhonePattern: `Formato: + (opcional) y 12 a 15 digitos`,
|
||||
errorMessageRequired: 'este campo es requerido.',
|
||||
errorMessageMaxLength: (maxLen: number) => `debe contener ${maxLen} caracteres or menos`,
|
||||
errorMessagePhonePattern: `formato: + (opcional) y 12 a 15 digitos`,
|
||||
errorMessageRequired: 'este campo es requerido',
|
||||
errorNotification: 'hubo un error',
|
||||
goBack: 'volver',
|
||||
name: 'nombre',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const environment = {
|
||||
prod: false,
|
||||
apiUrl: 'http://192.168.1.3:4444',
|
||||
apiUrl: 'http://192.168.1.3:8080',
|
||||
};
|
||||
|
||||