diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 7c6d99f..4b99dc2 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -19,6 +19,7 @@ import { ApplianceRegistrationModule } from './pages/appliance-registration/appl
import { AlertConfirmationModule } from './pages/components/alert-confirmation/alert-confirmation.module';
import { ProductModule } from './pages/product/product.module';
import { ModalProductModule } from './pages/components/modal-product/modal-product.module';
+import { PaymentModule } from './pages/payment/payment.module';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
@@ -33,6 +34,7 @@ export function HttpLoaderFactory(http: HttpClient) {
HomeModule,
DashboardModule,
ProductModule,
+ PaymentModule,
ReactiveFormsModule,
HttpClientModule,
TranslateModule.forRoot({
diff --git a/src/app/constants/routes.constants.ts b/src/app/constants/routes.constants.ts
index 117de20..e2aa545 100644
--- a/src/app/constants/routes.constants.ts
+++ b/src/app/constants/routes.constants.ts
@@ -5,6 +5,5 @@ export const RoutesConstants = {
dashboard: '/pages/:userId/home',
form: '/pages/:userId/form',
product: '/pages/:userId/product',
- root: '/',
+ payment: '/pages/:userId/payment/:id',
};
-
diff --git a/src/app/models/payment.ts b/src/app/models/payment.ts
new file mode 100644
index 0000000..af219a2
--- /dev/null
+++ b/src/app/models/payment.ts
@@ -0,0 +1,11 @@
+export interface Payment {
+ user_id: number;
+ full_name: string;
+ email: string;
+ telephone_number: string;
+ card_type: string;
+ card_number: string;
+ security_code: string;
+ amount_payable: number;
+ product_id: number;
+}
diff --git a/src/app/pages/components/menu/menu.component.html b/src/app/pages/components/menu/menu.component.html
index d6975a7..76f0251 100644
--- a/src/app/pages/components/menu/menu.component.html
+++ b/src/app/pages/components/menu/menu.component.html
@@ -22,7 +22,6 @@
translate }}
{{
'header.seguimiento_productos' | translate }}
- {{ 'header.gestion_pagos' | translate }}
@@ -70,4 +69,3 @@
-
diff --git a/src/app/pages/components/menu/menu.component.ts b/src/app/pages/components/menu/menu.component.ts
index 9bec36d..a979fec 100644
--- a/src/app/pages/components/menu/menu.component.ts
+++ b/src/app/pages/components/menu/menu.component.ts
@@ -24,6 +24,7 @@ export class MenuComponent {
currentLanguage: 'en' | 'es' = 'es';
languages = LanguageConstants;
userId: string | null = localStorage.getItem('userId');
+ paymentId: string | undefined;
constructor(private translationService: TranslationService) {
this.avatar = ImageConstants.avatar;
@@ -31,7 +32,7 @@ export class MenuComponent {
this.userLastName = localStorage.getItem('userLastName');
}
- toggleMenu() : void{
+ toggleMenu(): void {
this.showMenu = !this.showMenu;
}
@@ -50,8 +51,8 @@ export class MenuComponent {
this.router.navigate(['']);
}
- changeLanguage(language: 'en' | 'es', event: Event) : void{
- event.preventDefault();
+ changeLanguage(language: 'en' | 'es', event: Event): void {
+ event.preventDefault();
this.translationService.setLanguage(language);
this.currentLanguage = language;
this.closeMenu();
diff --git a/src/app/pages/components/modal-product/modal-product.component.html b/src/app/pages/components/modal-product/modal-product.component.html
index dbf1bc6..ae524d3 100644
--- a/src/app/pages/components/modal-product/modal-product.component.html
+++ b/src/app/pages/components/modal-product/modal-product.component.html
@@ -18,7 +18,8 @@
-
+
{{ product.appliance_type }}
@@ -64,7 +65,7 @@ {{ 'us
-
diff --git a/src/app/pages/components/modal-product/modal-product.component.ts b/src/app/pages/components/modal-product/modal-product.component.ts
index ab71ce4..63576f8 100644
--- a/src/app/pages/components/modal-product/modal-product.component.ts
+++ b/src/app/pages/components/modal-product/modal-product.component.ts
@@ -1,14 +1,16 @@
-import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import { Component, EventEmitter, inject, OnInit, Output } from '@angular/core';
import { Product } from 'src/app/models/product';
import { ProductModalService } from '../../services/product-modal.service';
import { User } from 'src/app/models/user';
+import { Router } from '@angular/router';
@Component({
selector: 'app-modal-product',
templateUrl: './modal-product.component.html',
- styleUrls: ['./modal-product.component.css']
+ styleUrls: ['./modal-product.component.css'],
})
export class ModalProductComponent implements OnInit {
+ private readonly router: Router = inject(Router);
@Output() alertClosed = new EventEmitter();
product: Product | null = null;
user: User | null = null;
@@ -17,13 +19,10 @@ export class ModalProductComponent implements OnInit {
constructor(private productModalService: ProductModalService) {}
ngOnInit(): void {
- this.productModalService.currentProduct.subscribe(product => {
+ this.productModalService.currentProduct.subscribe((product) => {
this.product = product;
- });
- this.productModalService.currentUser.subscribe(user => {
- this.user = user;
- if (this.user && this.product) {
- this.isOpenModal = true;
+ if (this.product) {
+ localStorage.setItem('currentProduct', JSON.stringify(this.product));
}
});
}
@@ -33,4 +32,8 @@ export class ModalProductComponent implements OnInit {
this.isOpenModal = false;
this.productModalService.closeModal();
}
+
+ navigateToPayment(userId: number, productId: number): void {
+ this.router.navigate([`/pages/${userId}/payment/${productId}`]);
+ }
}
diff --git a/src/app/pages/pages-routing.module.ts b/src/app/pages/pages-routing.module.ts
index c67a5d0..015b9e2 100644
--- a/src/app/pages/pages-routing.module.ts
+++ b/src/app/pages/pages-routing.module.ts
@@ -3,6 +3,7 @@ import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { ApplianceRegistrationComponent } from './appliance-registration/appliance-registration.component';
import { ProductComponent } from './product/product.component';
+import { PaymentComponent } from './payment/payment.component';
const routes: Routes = [
{
@@ -17,7 +18,10 @@ const routes: Routes = [
path: 'product',
component: ProductComponent,
},
-
+ {
+ path: 'payment/:id',
+ component: PaymentComponent,
+ },
];
@NgModule({
diff --git a/src/app/pages/pages.module.ts b/src/app/pages/pages.module.ts
index f191f0a..99c342c 100644
--- a/src/app/pages/pages.module.ts
+++ b/src/app/pages/pages.module.ts
@@ -5,7 +5,6 @@ import { PagesRoutingModule } from './pages-routing.module';
import { FormProductModule } from './components/form-product/form-product.module';
import { TranslateModule } from '@ngx-translate/core';
-import { ModalProductComponent } from './components/modal-product/modal-product.component';
@NgModule({
declarations: [],
diff --git a/src/app/pages/payment/payment.component.css b/src/app/pages/payment/payment.component.css
index e69de29..9a20654 100644
--- a/src/app/pages/payment/payment.component.css
+++ b/src/app/pages/payment/payment.component.css
@@ -0,0 +1,81 @@
+body {
+ background: linear-gradient(to right, rgba(0, 0, 255, 0.5), rgba(255, 255, 0, 0.5));
+ margin: 0;
+ font-family: Arial, sans-serif;
+}
+
+
+/* Contenedor de formulario y ticket */
+.flex {
+ display: flex;
+ }
+
+ /* Formulario */
+ .form-container, .ticket {
+ padding: 16px;
+ background: #fff;
+ border-radius: 8px;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+ }
+
+ /* Estilos del ticket */
+ .ticket {
+ border: 1px solid #000;
+ border-radius: 4px;
+ padding: 16px;
+ width: 100%;
+ background-color: #fff;
+ font-family: 'Courier New', Courier, monospace;
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
+ }
+
+ .ticket-header {
+ border-bottom: 2px dashed #000;
+ padding-bottom: 8px;
+ margin-bottom: 16px;
+ }
+
+ .ticket-title {
+ font-size: 18px;
+ margin: 0;
+ text-align: center;
+ }
+
+ .ticket-date {
+ font-size: 12px;
+ color: #666;
+ text-align: center;
+ }
+
+ .ticket-body {
+ margin-bottom: 16px;
+ }
+
+ .ticket-body p {
+ margin: 4px 0;
+ }
+
+ .ticket-footer {
+ text-align: center;
+ font-size: 12px;
+ color: #666;
+ border-top: 2px dashed #000;
+ padding-top: 8px;
+ }
+
+ /* Estilo del contenedor del ticket para centrar y dar margen */
+.ticket-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 20px;
+ border-radius: 12px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ background-color: #ffffff;
+ max-width: 400px;
+ margin: auto;
+}
+
+
+
+
diff --git a/src/app/pages/payment/payment.component.html b/src/app/pages/payment/payment.component.html
index d9cf5ff..b7cd77c 100644
--- a/src/app/pages/payment/payment.component.html
+++ b/src/app/pages/payment/payment.component.html
@@ -1 +1,155 @@
-payment works!
+
+
+
+
+
+
+
+
+
{{ 'contact_sales' | translate }}
+
+
{{ 'contact_sales_description' | translate }}
+
+
+
+
+
+
+
+
+
+
+ {{ 'client' | translate }}: {{ product?.user?.first_name }}
+ {{ product?.user?.last_name }}
+ {{ 'email_label' | translate }}: {{ product?.user?.email
+ }}
+ {{ 'phone' | translate }}: {{ product?.user?.phone_number
+ }}
+ {{ 'collection_address' | translate }}: {{
+ product?.collection_address }}
+ {{ 'service_type' | translate }}: {{ product?.service_type
+ }}
+ {{ 'problem_details' | translate }}: {{
+ product?.problem_details }}
+
+
+
+ {{ 'payment_form_full_name' | translate }}: {{
+ paymentForm.get('full_name')?.value || 'N/A' }}
+ {{ 'payment_form_email' | translate }}: {{
+ paymentForm.get('email')?.value || 'N/A' }}
+ {{ 'payment_form_phone' | translate }}: {{
+ paymentForm.get('telephone_number')?.value || 'N/A' }}
+ {{ 'payment_form_card' | translate }}: {{
+ paymentForm.get('card_number')?.value || 'N/A' }}
+ {{ 'payment_form_amount' | translate }}: {{
+ paymentForm.get('amount_payable')?.value || '0.00' }}
+
+
+
+
+
+
+
+
+
diff --git a/src/app/pages/payment/payment.component.spec.ts b/src/app/pages/payment/payment.component.spec.ts
deleted file mode 100644
index 3068378..0000000
--- a/src/app/pages/payment/payment.component.spec.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { PaymentComponent } from './payment.component';
-
-describe('PaymentComponent', () => {
- let component: PaymentComponent;
- let fixture: ComponentFixture;
-
- beforeEach(() => {
- TestBed.configureTestingModule({
- declarations: [PaymentComponent]
- });
- fixture = TestBed.createComponent(PaymentComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
diff --git a/src/app/pages/payment/payment.component.ts b/src/app/pages/payment/payment.component.ts
index 0f3a3af..0a282a7 100644
--- a/src/app/pages/payment/payment.component.ts
+++ b/src/app/pages/payment/payment.component.ts
@@ -1,10 +1,106 @@
-import { Component } from '@angular/core';
+import { Component, OnInit, inject } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { PaymentService } from '../services/payment.service';
+import { Payment } from 'src/app/models/payment';
+import { ActivatedRoute } from '@angular/router';
+import { Product } from 'src/app/models/product';
@Component({
selector: 'app-payment',
templateUrl: './payment.component.html',
- styleUrls: ['./payment.component.css']
+ styleUrls: ['./payment.component.css'],
})
export class PaymentComponent {
+ private readonly fb: FormBuilder = inject(FormBuilder);
+ paymentForm: FormGroup;
+ userId: number | undefined;
+ productId: number | undefined;
+ product: Product | null = null;
+ currentDate: string = new Date().toLocaleDateString();
+ constructor(
+ private paymentService: PaymentService,
+ private route: ActivatedRoute
+ ) {
+ this.getid();
+ this.paymentForm = this.buildForm();
+ this.getProductFromLocalStorage();
+
+ this.paymentForm.valueChanges.subscribe((values) => {
+ this.updateTicket();
+ });
+ }
+
+ private buildForm(): FormGroup {
+ return this.fb.group({
+ user_id: [this.userId, Validators.required],
+ full_name: ['', [Validators.required, Validators.minLength(2)]],
+ email: ['', [Validators.required, Validators.email]],
+ telephone_number: [
+ '',
+ [Validators.required, Validators.pattern('^[0-9]{10,15}$')],
+ ],
+ card_type: ['', Validators.required],
+ card_number: [
+ '',
+ [Validators.required, Validators.pattern('^[0-9]{16}$')],
+ ],
+ security_code: [
+ '',
+ [Validators.required, Validators.pattern('^[0-9]{3,4}$')],
+ ],
+ amount_payable: [
+ '',
+ [Validators.required, Validators.pattern('^[0-9]+(.[0-9]{1,2})?$')],
+ ],
+ product_id: [this.productId, Validators.required],
+ });
+ }
+
+ private getProductFromLocalStorage(): void {
+ const storedProduct = localStorage.getItem('currentProduct');
+ if (storedProduct) {
+ try {
+ this.product = JSON.parse(storedProduct) as Product;
+ } catch (error) {
+ console.error('Error parsing stored product:', error);
+ }
+ }
+ }
+
+ private updateTicket(): void {
+ this.currentDate = new Date().toLocaleDateString();
+ }
+
+ getid() {
+ return this.route.paramMap.subscribe((params) => {
+ const userIdParam = params.get('userId');
+ const productIdParam = params.get('id');
+
+ this.userId = userIdParam ? +userIdParam : undefined;
+ this.productId = productIdParam ? +productIdParam : undefined;
+
+ if (!isNaN(this.userId!) && !isNaN(this.productId!)) {
+ this.paymentForm.patchValue({
+ user_id: this.userId,
+ product_id: this.productId,
+ });
+ }
+ });
+ }
+
+ onSubmit(): void {
+ if (this.paymentForm.valid) {
+ const paymentData: Payment = this.paymentForm.value;
+ this.paymentService.registerPayment(paymentData).subscribe((response) => {
+ if (response) {
+ alert('Pago registrado correctamente');
+ } else {
+ alert('Error al registrar el pago');
+ }
+ });
+ } else {
+ alert('Por favor, completa todos los campos correctamente.');
+ }
+ }
}
diff --git a/src/app/pages/payment/payment.module.ts b/src/app/pages/payment/payment.module.ts
index e5966a0..452e2bb 100644
--- a/src/app/pages/payment/payment.module.ts
+++ b/src/app/pages/payment/payment.module.ts
@@ -2,13 +2,24 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PaymentRoutingModule } from './payment-routing.module';
+import { PaymentComponent } from './payment.component';
+import { MenuModule } from '../components/menu/menu.module';
+import { FooterModule } from '../components/footer/footer.module';
+import { TranslateModule } from '@ngx-translate/core';
+import { ReactiveFormsModule } from '@angular/forms';
+import { HttpClientModule } from '@angular/common/http';
@NgModule({
- declarations: [],
+ declarations: [PaymentComponent],
imports: [
CommonModule,
- PaymentRoutingModule
+ PaymentRoutingModule,
+ MenuModule,
+ FooterModule,
+ TranslateModule,
+ ReactiveFormsModule,
+ HttpClientModule
]
})
export class PaymentModule { }
diff --git a/src/app/pages/services/payment.service.ts b/src/app/pages/services/payment.service.ts
new file mode 100644
index 0000000..0a0dd32
--- /dev/null
+++ b/src/app/pages/services/payment.service.ts
@@ -0,0 +1,18 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs';
+import { Payment } from 'src/app/models/payment';
+import { environment } from 'src/environments/environment';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class PaymentService {
+ private apiUrl = `${environment.apiUrl}/payments`;
+
+ constructor(private http: HttpClient) {}
+
+ registerPayment(cardDetails: Payment): Observable {
+ return this.http.post(this.apiUrl, cardDetails);
+ }
+}
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index 56741ed..212b7ec 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -234,9 +234,49 @@
"PAY_NOW": "Pay now",
"damagedApplianceImageAlt": "Image of the damaged appliance",
"applianceTypeAlt": "Type of appliance",
- "INVALID_APPLICATION_DATE": "Invalid application date.",
+ "INVALID_APPLICATION_DATE": "Invalid application date.",
"INVALID_SERVICE_TYPE": "Invalid service type.",
"SERVICE_COMPLETED": "The repair/maintenance is complete.",
"TIMER_FORMAT": "{{days}}d {{hours}}h {{minutes}}m {{seconds}}s",
- "DATE_INVALID": "Invalid application date."
+ "DATE_INVALID": "Invalid application date.",
+ "contact_sales": "Make a Payment",
+ "contact_sales_description": "Complete your payment details below to finalize your purchase.",
+ "card_number": "Card Number",
+ "card_number_placeholder": "Enter card number",
+ "card_type": "Card Type",
+ "card_type_placeholder": "Enter card type",
+ "security_code": "Security Code (CVV)",
+ "security_code_placeholder": "CVV",
+ "full_name": "Full Name",
+ "full_name_placeholder": "Enter your full name",
+ "email_placeholder": "Enter your email",
+ "telephone_number": "Phone Number",
+ "telephone_number_placeholder": "Enter your phone number",
+ "amount_payable": "Amount Payable",
+ "amount_payable_placeholder": "Enter amount",
+ "privacy_policy": "By selecting this, you agree to our",
+ "privacy_policy_link": "privacy policy",
+ "submit_button": "Make Payment",
+ "service_ticket_title": "Service Ticket - {{appliance_type}}",
+ "service_ticket_date": "Date: {{application_date}}",
+ "client": "Client",
+ "email_label": "Email",
+ "collection_address": "Collection Address",
+ "service_type": "Service Type",
+ "problem_details": "Problem Details",
+ "damaged_appliance_image": "Damaged Appliance Image",
+ "payment_ticket_title": "Payment Ticket",
+ "payment_ticket_date": "Date: {{currentDate}}",
+ "payment_form_full_name": "Full Name",
+ "payment_form_email": "Email",
+ "payment_form_phone": "Phone",
+ "payment_form_card": "Card",
+ "payment_form_amount": "Amount to Pay",
+ "thank_you": "Thank you for your purchase.",
+ "CARD_TYPE": "Tipo de tarjeta",
+ "SELECT_CARD_TYPE": "Seleccione el tipo de tarjeta",
+ "VISA": "Visa",
+ "MASTERCARD": "MasterCard",
+ "AMERICAN_EXPRESS": "American Express",
+ "DISCOVER": "Discover"
}
diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json
index fa0a758..799cca0 100644
--- a/src/assets/i18n/es.json
+++ b/src/assets/i18n/es.json
@@ -232,12 +232,51 @@
"email": "Correo Electrónico",
"phone": "Teléfono",
"address": "Dirección",
- "PAY_NOW": "Pagar Ahora",
+ "PAY_NOW": "Pagar Ahora",
"damagedApplianceImageAlt": "Imagen del electrodoméstico dañado",
"applianceTypeAlt": "Tipo de electrodoméstico",
- "INVALID_APPLICATION_DATE": "Fecha de aplicación no válida.",
+ "INVALID_APPLICATION_DATE": "Fecha de aplicación no válida.",
"INVALID_SERVICE_TYPE": "Tipo de servicio no válido.",
"SERVICE_COMPLETED": "La reparación/mantenimiento está completo.",
"TIMER_FORMAT": "{{days}}d {{hours}}h {{minutes}}m {{seconds}}s",
- "DATE_INVALID": "Fecha de aplicación no válida."
+ "DATE_INVALID": "Fecha de aplicación no válida.",
+ "contact_sales": "Realizar Pago",
+ "contact_sales_description": "Complete los detalles de pago a continuación para finalizar su compra.",
+ "card_number": "Número de tarjeta",
+ "card_number_placeholder": "Ingrese el número de tarjeta",
+ "CARD_TYPE": "Tipo de tarjeta",
+ "SELECT_CARD_TYPE": "Seleccione el tipo de tarjeta",
+ "VISA": "Visa",
+ "MASTERCARD": "MasterCard",
+ "AMERICAN_EXPRESS": "American Express",
+ "DISCOVER": "Discover",
+ "card_type_placeholder": "Ingrese el tipo de tarjeta",
+ "security_code": "Código de seguridad (CVV)",
+ "security_code_placeholder": "CVV",
+ "full_name": "Nombre completo",
+ "full_name_placeholder": "Ingrese su nombre completo",
+ "email_placeholder": "Ingrese su email",
+ "telephone_number": "Número de teléfono",
+ "telephone_number_placeholder": "Ingrese su número de teléfono",
+ "amount_payable": "Monto a pagar",
+ "amount_payable_placeholder": "Ingrese el monto",
+ "privacy_policy": "Al seleccionar esto, aceptas nuestra",
+ "privacy_policy_link": "política de privacidad",
+ "submit_button": "Realizar Pago",
+ "service_ticket_title": "Ticket de Servicio - {{appliance_type}}",
+ "service_ticket_date": "Fecha: {{application_date}}",
+ "client": "Cliente",
+ "email_label": "Email",
+ "collection_address": "Dirección de Recolección",
+ "service_type": "Tipo de Servicio",
+ "problem_details": "Detalles del Problema",
+ "damaged_appliance_image": "Imagen del Electrodoméstico Dañado",
+ "payment_ticket_title": "Ticket de Pago",
+ "payment_ticket_date": "Fecha",
+ "payment_form_full_name": "Nombre Completo",
+ "payment_form_email": "Email",
+ "payment_form_phone": "Teléfono",
+ "payment_form_card": "Tarjeta",
+ "payment_form_amount": "Monto a Pagar",
+ "thank_you": "Gracias por su compra."
}