aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+about
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-01-10 11:12:41 +0100
committerChocobozzz <me@florianbigard.com>2019-01-10 11:32:38 +0100
commitd3e56c0c4b307c99e83fbafb7f2c5884cbc20055 (patch)
tree39976ee10a49fa2b9d7eb87437f59c872e7db0b8 /client/src/app/+about
parent3866f1a02f73665541468fbadcc3cd2cc459aef2 (diff)
downloadPeerTube-d3e56c0c4b307c99e83fbafb7f2c5884cbc20055.tar.gz
PeerTube-d3e56c0c4b307c99e83fbafb7f2c5884cbc20055.tar.zst
PeerTube-d3e56c0c4b307c99e83fbafb7f2c5884cbc20055.zip
Implement contact form in the client
Diffstat (limited to 'client/src/app/+about')
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.html8
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.scss16
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.ts17
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.html50
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.scss11
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.ts72
-rw-r--r--client/src/app/+about/about.module.ts4
7 files changed, 170 insertions, 8 deletions
diff --git a/client/src/app/+about/about-instance/about-instance.component.html b/client/src/app/+about/about-instance/about-instance.component.html
index 37ff795f5..8c700752e 100644
--- a/client/src/app/+about/about-instance/about-instance.component.html
+++ b/client/src/app/+about/about-instance/about-instance.component.html
@@ -1,7 +1,9 @@
1<div class="row"> 1<div class="row">
2 <div class="col-md-12 col-xl-6"> 2 <div class="col-md-12 col-xl-6">
3 <div i18n class="about-instance-title"> 3 <div class="about-instance-title">
4 About {{ instanceName }} instance 4 <div i18n>About {{ instanceName }} instance</div>
5
6 <div *ngIf="isContactFormEnabled" (click)="openContactModal()" i18n role="button" class="contact-admin">Contact administrator</div>
5 </div> 7 </div>
6 8
7 <div class="short-description"> 9 <div class="short-description">
@@ -46,3 +48,5 @@
46 <my-instance-features-table></my-instance-features-table> 48 <my-instance-features-table></my-instance-features-table>
47 </div> 49 </div>
48</div> 50</div>
51
52<my-contact-admin-modal #contactAdminModal></my-contact-admin-modal>
diff --git a/client/src/app/+about/about-instance/about-instance.component.scss b/client/src/app/+about/about-instance/about-instance.component.scss
index b451e85aa..75cf57322 100644
--- a/client/src/app/+about/about-instance/about-instance.component.scss
+++ b/client/src/app/+about/about-instance/about-instance.component.scss
@@ -2,9 +2,19 @@
2@import '_mixins'; 2@import '_mixins';
3 3
4.about-instance-title { 4.about-instance-title {
5 font-size: 20px; 5 display: flex;
6 font-weight: bold; 6 justify-content: space-between;
7 margin-bottom: 15px; 7
8 & > div {
9 font-size: 20px;
10 font-weight: bold;
11 margin-bottom: 15px;
12 }
13
14 & > .contact-admin {
15 @include peertube-button;
16 @include orange-button;
17 }
8} 18}
9 19
10.section-title { 20.section-title {
diff --git a/client/src/app/+about/about-instance/about-instance.component.ts b/client/src/app/+about/about-instance/about-instance.component.ts
index 36e7a8e5b..d3ee8a1e4 100644
--- a/client/src/app/+about/about-instance/about-instance.component.ts
+++ b/client/src/app/+about/about-instance/about-instance.component.ts
@@ -1,7 +1,9 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit, ViewChild } from '@angular/core'
2import { Notifier, ServerService } from '@app/core' 2import { Notifier, ServerService } from '@app/core'
3import { MarkdownService } from '@app/videos/shared' 3import { MarkdownService } from '@app/videos/shared'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component'
6import { InstanceService } from '@app/shared/instance/instance.service'
5 7
6@Component({ 8@Component({
7 selector: 'my-about-instance', 9 selector: 'my-about-instance',
@@ -9,6 +11,8 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
9 styleUrls: [ './about-instance.component.scss' ] 11 styleUrls: [ './about-instance.component.scss' ]
10}) 12})
11export class AboutInstanceComponent implements OnInit { 13export class AboutInstanceComponent implements OnInit {
14 @ViewChild('contactAdminModal') contactAdminModal: ContactAdminModalComponent
15
12 shortDescription = '' 16 shortDescription = ''
13 descriptionHTML = '' 17 descriptionHTML = ''
14 termsHTML = '' 18 termsHTML = ''
@@ -16,6 +20,7 @@ export class AboutInstanceComponent implements OnInit {
16 constructor ( 20 constructor (
17 private notifier: Notifier, 21 private notifier: Notifier,
18 private serverService: ServerService, 22 private serverService: ServerService,
23 private instanceService: InstanceService,
19 private markdownService: MarkdownService, 24 private markdownService: MarkdownService,
20 private i18n: I18n 25 private i18n: I18n
21 ) {} 26 ) {}
@@ -32,8 +37,12 @@ export class AboutInstanceComponent implements OnInit {
32 return this.serverService.getConfig().signup.allowed 37 return this.serverService.getConfig().signup.allowed
33 } 38 }
34 39
40 get isContactFormEnabled () {
41 return this.serverService.getConfig().email.enabled && this.serverService.getConfig().contactForm.enabled
42 }
43
35 ngOnInit () { 44 ngOnInit () {
36 this.serverService.getAbout() 45 this.instanceService.getAbout()
37 .subscribe( 46 .subscribe(
38 res => { 47 res => {
39 this.shortDescription = res.instance.shortDescription 48 this.shortDescription = res.instance.shortDescription
@@ -45,4 +54,8 @@ export class AboutInstanceComponent implements OnInit {
45 ) 54 )
46 } 55 }
47 56
57 openContactModal () {
58 return this.contactAdminModal.show()
59 }
60
48} 61}
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.html b/client/src/app/+about/about-instance/contact-admin-modal.component.html
new file mode 100644
index 000000000..2b3fb32f3
--- /dev/null
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.html
@@ -0,0 +1,50 @@
1<ng-template #modal>
2 <div class="modal-header">
3 <h4 i18n class="modal-title">Contact {{ instanceName }} administrator</h4>
4 <span class="close" aria-label="Close" role="button" (click)="hide()"></span>
5 </div>
6
7 <div class="modal-body">
8
9 <form novalidate [formGroup]="form" (ngSubmit)="sendForm()">
10 <div class="form-group">
11 <label i18n for="fromName">Your name</label>
12 <input
13 type="text" id="fromName"
14 formControlName="fromName" [ngClass]="{ 'input-error': formErrors.fromName }"
15 >
16 <div *ngIf="formErrors.fromName" class="form-error">{{ formErrors.fromName }}</div>
17 </div>
18
19 <div class="form-group">
20 <label i18n for="fromEmail">Your email</label>
21 <input
22 type="text" id="fromEmail"
23 formControlName="fromEmail" [ngClass]="{ 'input-error': formErrors['fromEmail'] }"
24 >
25 <div *ngIf="formErrors.fromEmail" class="form-error">{{ formErrors.fromEmail }}</div>
26 </div>
27
28 <div class="form-group">
29 <label i18n for="body">Your message</label>
30 <textarea id="body" formControlName="body" [ngClass]="{ 'input-error': formErrors['body'] }">
31 </textarea>
32 <div *ngIf="formErrors.body" class="form-error">{{ formErrors.body }}</div>
33 </div>
34
35 <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
36
37 <div class="form-group inputs">
38 <span i18n class="action-button action-button-cancel" (click)="hide()">
39 Cancel
40 </span>
41
42 <input
43 type="submit" i18n-value value="Submit" class="action-button-submit"
44 [disabled]="!form.valid"
45 >
46 </div>
47 </form>
48
49 </div>
50</ng-template>
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.scss b/client/src/app/+about/about-instance/contact-admin-modal.component.scss
new file mode 100644
index 000000000..260d77888
--- /dev/null
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.scss
@@ -0,0 +1,11 @@
1@import 'variables';
2@import 'mixins';
3
4input[type=text] {
5 @include peertube-input-text(340px);
6 display: block;
7}
8
9textarea {
10 @include peertube-textarea(100%, 200px);
11}
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.ts b/client/src/app/+about/about-instance/contact-admin-modal.component.ts
new file mode 100644
index 000000000..2f707bd53
--- /dev/null
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.ts
@@ -0,0 +1,72 @@
1import { Component, OnInit, ViewChild } from '@angular/core'
2import { Notifier } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
5import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
6import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
7import { FormReactive, InstanceValidatorsService } from '@app/shared'
8import { InstanceService } from '@app/shared/instance/instance.service'
9
10@Component({
11 selector: 'my-contact-admin-modal',
12 templateUrl: './contact-admin-modal.component.html',
13 styleUrls: [ './contact-admin-modal.component.scss' ]
14})
15export class ContactAdminModalComponent extends FormReactive implements OnInit {
16 @ViewChild('modal') modal: NgbModal
17
18 error: string
19
20 private openedModal: NgbModalRef
21
22 constructor (
23 protected formValidatorService: FormValidatorService,
24 private modalService: NgbModal,
25 private instanceValidatorsService: InstanceValidatorsService,
26 private instanceService: InstanceService,
27 private notifier: Notifier,
28 private i18n: I18n
29 ) {
30 super()
31 }
32
33 ngOnInit () {
34 this.buildForm({
35 fromName: this.instanceValidatorsService.FROM_NAME,
36 fromEmail: this.instanceValidatorsService.FROM_EMAIL,
37 body: this.instanceValidatorsService.BODY
38 })
39 }
40
41 show () {
42 this.openedModal = this.modalService.open(this.modal, { keyboard: false })
43 }
44
45 hide () {
46 this.form.reset()
47 this.error = undefined
48
49 this.openedModal.close()
50 this.openedModal = null
51 }
52
53 sendForm () {
54 const fromName = this.form.value['fromName']
55 const fromEmail = this.form.value[ 'fromEmail' ]
56 const body = this.form.value[ 'body' ]
57
58 this.instanceService.contactAdministrator(fromEmail, fromName, body)
59 .subscribe(
60 () => {
61 this.notifier.success(this.i18n('Your message has been sent.'))
62 this.hide()
63 },
64
65 err => {
66 this.error = err.status === 403
67 ? this.i18n('You already sent this form recently')
68 : err.message
69 }
70 )
71 }
72}
diff --git a/client/src/app/+about/about.module.ts b/client/src/app/+about/about.module.ts
index ff6e8ef41..9c6b29740 100644
--- a/client/src/app/+about/about.module.ts
+++ b/client/src/app/+about/about.module.ts
@@ -5,6 +5,7 @@ import { AboutComponent } from './about.component'
5import { SharedModule } from '../shared' 5import { SharedModule } from '../shared'
6import { AboutInstanceComponent } from '@app/+about/about-instance/about-instance.component' 6import { AboutInstanceComponent } from '@app/+about/about-instance/about-instance.component'
7import { AboutPeertubeComponent } from '@app/+about/about-peertube/about-peertube.component' 7import { AboutPeertubeComponent } from '@app/+about/about-peertube/about-peertube.component'
8import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component'
8 9
9@NgModule({ 10@NgModule({
10 imports: [ 11 imports: [
@@ -15,7 +16,8 @@ import { AboutPeertubeComponent } from '@app/+about/about-peertube/about-peertub
15 declarations: [ 16 declarations: [
16 AboutComponent, 17 AboutComponent,
17 AboutInstanceComponent, 18 AboutInstanceComponent,
18 AboutPeertubeComponent 19 AboutPeertubeComponent,
20 ContactAdminModalComponent
19 ], 21 ],
20 22
21 exports: [ 23 exports: [