Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat: implemented a feature to allow users to send feedback to featbit maintainer #271

Merged
merged 4 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,47 @@
</nz-breadcrumb>

<div class="header-btns">
<div class="guide-btn" nz-tooltip="Quick Start Guide" i18n-nz-tooltip="@@common.quick-start-guide" (click)="onQuickStartGuideClick()">
<div class="header-btn feedback" (click)="openFeedbackModal()" i18n="@@common.feedback">Feedback</div>
<div class="header-btn" nzTooltipPlacement="bottom" nz-tooltip="Quick Start Guide" i18n-nz-tooltip="@@common.quick-start-guide" (click)="onQuickStartGuideClick()">
<span nz-icon nzType="read" nzTheme="outline"></span>
</div>
</div>
<div style="display:flex;justify-content: flex-end;align-items: center">
<div class="header-info">
<div class="org-proj-env">
<div class="org-btns">
<div class="header-info">
<div class="org-proj-env">
<span [routerLink]="['/organizations']">
<i nz-icon nzType="icons:icon-org"></i>
{{currentOrganization?.name}}
</span>
<span (click)="envModalVisible=true">
<span (click)="envModalVisible=true">
<i nz-icon nzType="icons:icon-proj"></i>
{{currentProjectEnv?.projectName}}
{{currentProjectEnv?.projectName}}
</span>
<span (click)="envModalVisible=true" nz-popover i18n-nz-popover="@@common.env-secret" nzPopoverTitle="Environment Secret"
[nzPopoverContent]="environmentSecretContent"
style="background-color: transparent;"
nzPopoverOverlayClassName="env-secret-popover">
<span (click)="envModalVisible=true" nz-popover i18n-nz-popover="@@common.env-secret" nzPopoverTitle="Environment Secret"
[nzPopoverContent]="environmentSecretContent"
style="background-color: transparent;"
nzPopoverOverlayClassName="env-secret-popover">

<i nz-icon nzType="icons:icon-env"></i>
{{currentProjectEnv?.envName}}
{{currentProjectEnv?.envName}}

<ng-template #environmentSecretContent>
<ng-template #environmentSecretContent>
<div class="env-secret-popover-content" (click)="copyText($event, currentProjectEnv?.envSecret)">
<i class="copy-icon" nz-icon
nzType="icons:icon-copy"></i>
nzType="icons:icon-copy"></i>
{{currentProjectEnv?.envSecret}}
</div>
</ng-template>
</span>
</div>
</div>

<div class="switch" (click)="envModalVisible=true">
<button class="switch-link-btn" nz-button nzType="link">
<i nz-icon nzType="icons:icon-swap"></i>
</button>
<div class="switch" (click)="envModalVisible=true">
<button class="switch-link-btn" nz-button nzType="link">
<i nz-icon nzType="icons:icon-swap"></i>
</button>
</div>
</div>
</div>
</div>

</section>

<nz-modal nzCentered nzWidth="792" [nzVisible]="envModalVisible" [nzFooter]="modalFooter"
Expand Down Expand Up @@ -80,3 +80,34 @@
<button nz-button nzType="primary" (click)="envModalConfirm()" i18n="@@common.save">Save</button>
</ng-template>
</nz-modal>

<nz-modal [nzVisible]="feedbackModalVisible"
[nzTitle]="feedbackModalTitle"
[nzCentered]="true"
[nzContent]="feedbackModalContent"
[nzFooter]="feedbackModalFooter"
(nzOnCancel)="feedbackModalVisible=false">
<ng-template #feedbackModalTitle><ng-container i18n="@@common.send-feedback">Send feedback</ng-container></ng-template>
<ng-template #feedbackModalContent>
<form nz-form [formGroup]="feedbackForm" nzLayout="vertical">
<nz-form-item>
<nz-form-label nzRequired i18n="@@common.email">Email</nz-form-label>
<nz-form-control nzHasFeedback i18n-nzErrorTip="@@common.email-cannot-be-empty" nzErrorTip="Email cannot be empty">
<input nz-input formControlName="email" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired i18n="@@common.message">Message</nz-form-label>
<nz-form-control nzHasFeedback nzErrorTip="Message is mandatory" i18n-nzErrorTip="@@common.message-mandatory">
<textarea nz-input formControlName="message" i18n-placeholder="@@common.message-placeholder" placeholder="Have you any feedback for us?">
</textarea>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>

<ng-template #feedbackModalFooter>
<button nz-button nzType="default" (click)="feedbackModalVisible=false" i18n="@@common.cancel">Cancel</button>
<button nz-button nzType="primary" [nzLoading]="sendingFeedback" [disabled]="feedbackForm.invalid" (click)="sendFeedback()" i18n="@@common.send">Send</button>
</ng-template>
</nz-modal>
Original file line number Diff line number Diff line change
Expand Up @@ -163,32 +163,37 @@ i:hover {
}

.header-btns {
width: 60px;
height: 60px;
float: right;
display: flex;
flex-direction: row;
align-items: center;
padding: 12px 8px;
background: @grey5-color;
border-radius: 42px;
gap: 32px;
position: relative;
margin-left: auto;
margin-right: 10px;

.guide-btn {
.header-btn {
font-size: 18px;
cursor: pointer;
padding: 8px 13px;
margin-top: 3px;
border-radius: 42px;
box-sizing: border-box;

&.feedback {
font-size: 14px;
font-weight: 700;

&:hover {
color: @green70-color;
}
}
}

.guide-btn:hover {
.header-btn:hover {
span {
color: @green70-color;
}
}

.org-btns {
display:flex;
justify-content: flex-end;
align-items: center
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { NzMessageService } from "ng-zorro-antd/message";
import { MessageQueueService } from "@services/message-queue.service";
import { Observable } from "rxjs";
import { copyToClipboard } from '@utils/index';
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { FeedbackService } from "@services/feedback.service";

@Component({
selector: 'app-header',
Expand Down Expand Up @@ -38,11 +40,18 @@ export class HeaderComponent implements OnInit {
private organizationService: OrganizationService,
private projectService: ProjectService,
private message: NzMessageService,
private fb: FormBuilder,
private feedbackService: FeedbackService,
private readonly breadcrumbService: BreadcrumbService,
private permissionsService: PermissionsService,
private messageQueueService: MessageQueueService,
) {
this.breadcrumbs$ = breadcrumbService.breadcrumbs$;

this.feedbackForm = this.fb.group({
email: ['', [Validators.required, Validators.email]],
message:['',[Validators.required]]
});
}

ngOnInit(): void {
Expand Down Expand Up @@ -151,4 +160,38 @@ export class HeaderComponent implements OnInit {
() => this.message.success($localize `:@@common.copy-success:Copied`)
);
}

// feedback
feedbackModalVisible = false;
sendingFeedback = false;
feedbackForm: FormGroup;

openFeedbackModal() {
this.feedbackModalVisible = true;
this.feedbackForm.reset();
}
sendFeedback() {
if (this.feedbackForm.invalid) {
for (const i in this.feedbackForm.controls) {
this.feedbackForm.controls[i].markAsDirty();
this.feedbackForm.controls[i].updateValueAndValidity();
}
}

this.sendingFeedback = true;
const { email, message } = this.feedbackForm.value;

this.feedbackService.sendFeedback(email, message).subscribe({
next: () => {
this.message.success($localize `:@@common.feedback-success-message:Thank you for sending us your feedback, we'll get back to you very soon!`);
},
error: () => {
this.message.error($localize `:@@common.feedback-failure-message:We were not able to send your feedback, Please try again!`);
},
complete: () => {
this.sendingFeedback = false;
this.feedbackModalVisible = false;
}
});
}
}
19 changes: 19 additions & 0 deletions modules/front-end/src/app/core/services/feedback.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";

@Injectable({
providedIn: 'root'
})
export class FeedbackService {
private url = "https://www.featbit.co/api/feedback";
private headers: HttpHeaders;

constructor(private http: HttpClient) {
this.headers = new HttpHeaders().set('token', 'uxeizS3tlCXRKLOi4GPtAU1OcVl3RkDR54HKlbt7tVZGaWTtmvfZYheQDUGLr4troWdksluYijZHGDKB');
}

sendFeedback(email: string, message: string): Observable<any> {
return this.http.post(this.url, { email, message }, { headers: this.headers });
}
}
Loading