contact form implementation
This commit is contained in:
parent
62ead2b2fe
commit
26e7bd5d44
@ -1,6 +1,7 @@
|
|||||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { ContactSidebarComponent } from './contact-sidebar/contact-sidebar.component';
|
import { ContactSidebarComponent } from './contact-sidebar/contact-sidebar.component';
|
||||||
@ -29,7 +30,8 @@ import { SpinnerComponent } from './spinner/spinner.component';
|
|||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
AppRoutingModule
|
AppRoutingModule,
|
||||||
|
FormsModule
|
||||||
],
|
],
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
providers: [httpInterceptorProviders],
|
providers: [httpInterceptorProviders],
|
||||||
|
|||||||
@ -16,21 +16,36 @@
|
|||||||
|
|
||||||
<h3 class="h3 form-title">Contact Form</h3>
|
<h3 class="h3 form-title">Contact Form</h3>
|
||||||
|
|
||||||
<form action="#" class="form" data-form>
|
<form class="form" #messageForm="ngForm" (ngSubmit)="sendMessage()">
|
||||||
|
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<input type="text" name="fullname" class="form-input" placeholder="Full name" required data-form-input>
|
<div>
|
||||||
|
<input type="text" name="fullname" maxlength="20" #fullName="ngModel" autocomplete="off" [(ngModel)]="messageModel.name" class="form-input" placeholder="Full name" required>
|
||||||
|
<em class="error" *ngIf="fullName.errors?.['required'] && fullName.touched">Full name is required</em>
|
||||||
|
</div>
|
||||||
|
|
||||||
<input type="email" name="email" class="form-input" placeholder="Email address" required data-form-input>
|
<div>
|
||||||
|
<input type="email" name="email" email #email="ngModel" autocomplete="off" [(ngModel)]="messageModel.fromEmail" class="form-input" placeholder="Email address" required>
|
||||||
|
<em class="error" *ngIf="email.errors?.['email'] && email.touched">Must be a valid email format</em>
|
||||||
|
<em class="error" *ngIf="email.errors?.['required'] && email.touched">Email is required</em>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<textarea name="message" class="form-input" placeholder="Your Message" required data-form-input></textarea>
|
<div class="text-area">
|
||||||
|
<textarea name="message" #message="ngModel" autocomplete="off" maxlength="500" [(ngModel)]="messageModel.content" class="form-input" placeholder="Your Message" required></textarea>
|
||||||
|
<em class="error" *ngIf="message.errors?.['required'] && message.touched">Message is required</em>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="form-btn" type="submit" disabled data-form-btn>
|
<button class="form-btn" type="submit" [disabled]="messageForm.form.invalid && messageForm.form.touched">
|
||||||
<i class="fa-regular fa-paper-plane"></i>
|
<i class="fa-regular fa-paper-plane"></i>
|
||||||
<span>Send Message</span>
|
<span>Send Message</span>
|
||||||
</button>
|
</button>
|
||||||
|
<div class="messageSentError" *ngIf="messageSentError">
|
||||||
|
Message not sent. Please try again.
|
||||||
|
</div>
|
||||||
|
<div class="messageSentSuccess" *ngIf="messageSentSuccess">
|
||||||
|
Message sent successfully.
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
.messageSentError {
|
||||||
|
margin:25px 0;
|
||||||
|
color: rgb(206, 87, 7);
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messageSentSuccess{
|
||||||
|
margin:25px 0;
|
||||||
|
color: green;
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
em.error{
|
||||||
|
padding: 2px 5px;
|
||||||
|
color: rgb(206, 87, 7);
|
||||||
|
//color: white;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { BaseComponent } from '../base/base.component';
|
|
||||||
import { CvService } from '../services/cv.service';
|
import { CvService } from '../services/cv.service';
|
||||||
import { ISideBar } from '../contact-sidebar/side-bar.model';
|
import { IContact } from './contact.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contact',
|
selector: 'app-contact',
|
||||||
@ -9,6 +8,21 @@ import { ISideBar } from '../contact-sidebar/side-bar.model';
|
|||||||
styleUrl: './contact.component.scss'
|
styleUrl: './contact.component.scss'
|
||||||
})
|
})
|
||||||
export class ContactComponent {
|
export class ContactComponent {
|
||||||
constructor(svc: CvService){
|
messageModel: IContact = {name: '', fromEmail: '', content: '' };
|
||||||
|
candidateId: number = 1;
|
||||||
|
messageSentError: boolean = false;
|
||||||
|
messageSentSuccess: boolean = false;
|
||||||
|
|
||||||
|
constructor(private svc: CvService){
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage() :void{
|
||||||
|
this.messageSentError = false;
|
||||||
|
this.messageSentSuccess = false;
|
||||||
|
|
||||||
|
this.svc.sendMessage(this.messageModel, this.candidateId).subscribe({
|
||||||
|
next: (response) => this.messageSentSuccess = response,
|
||||||
|
error: () => this.messageSentError = true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
src/app/contact/contact.model.ts
Normal file
5
src/app/contact/contact.model.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface IContact{
|
||||||
|
name: string;
|
||||||
|
fromEmail: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ import { IResume } from '../resume/resume.model';
|
|||||||
import { IBlog } from '../blog/blog.model';
|
import { IBlog } from '../blog/blog.model';
|
||||||
import { IProjects } from '../projects/projects.model';
|
import { IProjects } from '../projects/projects.model';
|
||||||
import { ISideBar } from '../contact-sidebar/side-bar.model';
|
import { ISideBar } from '../contact-sidebar/side-bar.model';
|
||||||
|
import { IContact } from '../contact/contact.model';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -63,4 +64,8 @@ export class CvService {
|
|||||||
}
|
}
|
||||||
return this.http.get<IBlog>(`/api/v1/cv/GetBlog/${candidateId}`);
|
return this.http.get<IBlog>(`/api/v1/cv/GetBlog/${candidateId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendMessage(contact: IContact, candidateId: number): Observable<boolean> {
|
||||||
|
return this.http.post<boolean>(`/api/v1/cv/SendMessage/${candidateId}`, contact);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1173,6 +1173,10 @@
|
|||||||
height: 120px;
|
height: 120px;
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
|
// margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.text-area{
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1533,7 +1537,8 @@
|
|||||||
|
|
||||||
.form-input { padding: 15px 20px; }
|
.form-input { padding: 15px 20px; }
|
||||||
|
|
||||||
textarea.form-input { margin-bottom: 30px; }
|
// textarea.form-input { margin-bottom: 30px; }
|
||||||
|
div.textarea { margin-bottom: 30px; }
|
||||||
|
|
||||||
.form-btn {
|
.form-btn {
|
||||||
--fs-6: 16px;
|
--fs-6: 16px;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user