adding ability to submit support tickets in-app.
added logos to the patient profile menu added link to fundraising doc in-app update fontawesome version. fixes #272
This commit is contained in:
parent
bbf5169a44
commit
cae3afce72
|
@ -0,0 +1,14 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
type SupportRequest struct {
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
RequestContent string `json:"request_content"`
|
||||||
|
|
||||||
|
CurrentPage string `json:"current_page"`
|
||||||
|
DistType string `json:"dist_type"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Flavor string `json:"flavor"`
|
||||||
|
Os string `json:"os"`
|
||||||
|
Arch string `json:"arch"`
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/fastenhealth/fasten-onprem/backend/pkg/models"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SupportRequest(c *gin.Context) {
|
||||||
|
|
||||||
|
var supportRequest models.SupportRequest
|
||||||
|
if err := c.ShouldBindJSON(&supportRequest); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//submit support request to Google Form
|
||||||
|
//https://medium.com/front-end-augustus-study-notes/custom-google-form-en-f7be4c27a98b
|
||||||
|
|
||||||
|
//source: https://docs.google.com/forms/d/e/1FAIpQLSfFxttuzE4mYNtQxa2XxsHw3uyNsxUzE-BeYF4JXxoKku3R5A/viewform
|
||||||
|
formUrl := "https://docs.google.com/forms/u/0/d/e/1FAIpQLSfFxttuzE4mYNtQxa2XxsHw3uyNsxUzE-BeYF4JXxoKku3R5A/formResponse"
|
||||||
|
|
||||||
|
supportRequestResponse, err := http.PostForm(formUrl, url.Values{
|
||||||
|
"entry.1688458216": {supportRequest.FullName},
|
||||||
|
"entry.153181769": {supportRequest.Email},
|
||||||
|
"entry.1194157548": {supportRequest.RequestContent},
|
||||||
|
"entry.108410483": {supportRequest.CurrentPage},
|
||||||
|
"entry.1640090028": {supportRequest.DistType},
|
||||||
|
"entry.882116507": {supportRequest.Flavor},
|
||||||
|
"entry.1331679697": {supportRequest.Version},
|
||||||
|
"entry.164864077": {supportRequest.Arch},
|
||||||
|
"entry.1469583108": {supportRequest.Os},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer supportRequestResponse.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(supportRequestResponse.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
//handle read response error
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()})
|
||||||
|
return
|
||||||
|
} else if supportRequestResponse.StatusCode != 200 {
|
||||||
|
//handle non 200 response
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": fmt.Sprintf("status code error: %d %s", supportRequestResponse.StatusCode, supportRequestResponse.Status)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", string(body))
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"success": true})
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ func (ae *AppEngine) Setup() (*gin.RouterGroup, *gin.Engine) {
|
||||||
//r.GET("/cors/*proxyPath", handler.CORSProxy)
|
//r.GET("/cors/*proxyPath", handler.CORSProxy)
|
||||||
//r.OPTIONS("/cors/*proxyPath", handler.CORSProxy)
|
//r.OPTIONS("/cors/*proxyPath", handler.CORSProxy)
|
||||||
api.GET("/glossary/code", handler.GlossarySearchByCode)
|
api.GET("/glossary/code", handler.GlossarySearchByCode)
|
||||||
|
api.POST("/support/request", handler.SupportRequest)
|
||||||
|
|
||||||
secure := api.Group("/secure").Use(middleware.RequireAuth())
|
secure := api.Group("/secure").Use(middleware.RequireAuth())
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,10 +67,121 @@
|
||||||
<span>Adminstrator</span>
|
<span>Adminstrator</span>
|
||||||
</div><!-- az-header-profile -->
|
</div><!-- az-header-profile -->
|
||||||
|
|
||||||
<a ngbTooltip="not yet implemented" class="dropdown-item"><i class="typcn typcn-time"></i> Activity Logs</a>
|
<a (click)="openSupportForm(content)" class="dropdown-item cursor-pointer"><i style="font-size: medium;" class="fas fa-question-circle"></i> Get Support</a>
|
||||||
<a (click)="signOut($event)" class="dropdown-item"><i class="typcn typcn-power-outline"></i> Sign Out</a>
|
<a class="dropdown-item cursor-pointer" href="https://docs.fastenhealth.com/FUNDRAISING.html" externalLink><i style="font-size: medium;" class="fas fa-hand-holding-medical"></i> Donate</a>
|
||||||
|
<a (click)="signOut($event)" class="dropdown-item cursor-pointer"><i style="font-size: medium;" class="fas fa-power-off"></i> Sign Out</a>
|
||||||
</div><!-- dropdown-menu -->
|
</div><!-- dropdown-menu -->
|
||||||
</div>
|
</div>
|
||||||
</div><!-- az-header-right -->
|
</div><!-- az-header-right -->
|
||||||
</div><!-- container -->
|
</div><!-- container -->
|
||||||
</div><!-- az-header -->
|
</div><!-- az-header -->
|
||||||
|
|
||||||
|
|
||||||
|
<ng-template #content let-modal>
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Get Support</h4>
|
||||||
|
<button type="button" class="btn close" aria-label="Close" (click)="modal.dismiss('Cross click')"><span aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<ngb-accordion #acc="ngbAccordion" activeIds="ngb-panel-0">
|
||||||
|
<ngb-panel title="File an Issue">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
|
||||||
|
<p>If you're having issues with Fasten Health, you can use this form to file a ticket.</p>
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<strong>Your Privacy is Important</strong> None of the information provided in this form will be made public,
|
||||||
|
however we will anonymize & summarize the content before creating a <a href="https://github.com/fastenhealth/fasten-onprem/issues" externalLink><i class="fab fa-github"></i> Github Issue</a> for tracking purposes.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form *ngIf="!submitSuccess; else supportRequestSuccess" (ngSubmit)="submitSupportForm()" #supportRequestForm="ngForm">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label class="az-content-label tx-11 tx-medium tx-gray-600">Name</label>
|
||||||
|
<input [(ngModel)]="newSupportRequest.full_name" name="full_name" #full_name="ngModel" required minlength="2" type="text" class="form-control" placeholder="Enter your name">
|
||||||
|
|
||||||
|
<div *ngIf="full_name.invalid && (full_name.dirty || full_name.touched)" class="alert alert-danger">
|
||||||
|
<div *ngIf="full_name.errors?.['required']">
|
||||||
|
Name is required.
|
||||||
|
</div>
|
||||||
|
<div *ngIf="full_name.errors?.['minlength']">
|
||||||
|
Name must be at least 2 characters long.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<label class="az-content-label tx-11 tx-medium tx-gray-600">Email Address</label>
|
||||||
|
<input [(ngModel)]="newSupportRequest.email" email name="emailAddr" #emailAddr="ngModel" required minlength="4" type="text" class="form-control" autocapitalize="none" placeholder="Enter your email address">
|
||||||
|
|
||||||
|
<div *ngIf="emailAddr.invalid && (emailAddr.dirty || emailAddr.touched)" class="alert alert-danger">
|
||||||
|
<div *ngIf="emailAddr.errors?.['required']">
|
||||||
|
Email Address is required.
|
||||||
|
</div>
|
||||||
|
<div *ngIf="emailAddr.errors?.['minlength']">
|
||||||
|
Email Address must be at least 4 characters long.
|
||||||
|
</div>
|
||||||
|
<div *ngIf="emailAddr.errors?.['email']">
|
||||||
|
Email Address must be a valid email address.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- form-group -->
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="az-content-label tx-11 tx-medium tx-gray-600">Issue Description</label>
|
||||||
|
<textarea [(ngModel)]="newSupportRequest.request_content" name="requestContent" #requestContent="ngModel" rows="3" class="form-control" placeholder="Please provide a detailed description of the issue that you're encountering" required minlength="4"></textarea>
|
||||||
|
|
||||||
|
<div *ngIf="requestContent.invalid && (requestContent.dirty || requestContent.touched)" class="alert alert-danger">
|
||||||
|
<div *ngIf="requestContent.errors?.['required']">
|
||||||
|
Issue Description is required.
|
||||||
|
</div>
|
||||||
|
<div *ngIf="requestContent.errors?.['minlength']">
|
||||||
|
Issue Description must be at least 4 characters long.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div><!-- form-group -->
|
||||||
|
|
||||||
|
<button [disabled]="!supportRequestForm.form.valid || loading" type="submit" class="btn btn-az-primary btn-block">Submit Issue</button>
|
||||||
|
<div *ngIf="errorMsg" class="alert alert-danger mt-3" role="alert">
|
||||||
|
<strong>Error</strong> {{errorMsg}}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<ng-template #supportRequestSuccess>
|
||||||
|
<div class="tx-center pd-y-20 pd-x-20">
|
||||||
|
<i class="far fa-check-square tx-100 tx-success lh-1 mg-t-20 d-inline-block"></i>
|
||||||
|
<h4 class="tx-success mg-b-20">Success!</h4>
|
||||||
|
<p class="mg-b-20 mg-x-20">Someone from the dev team will contact <br/>you shortly regarding your feedback. Thanks!</p>
|
||||||
|
<button type="button" (click)="resetSupportRequestForm()" class="btn btn-success pd-x-25">Continue</button>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
<ngb-panel title="Community Discussions & Support">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<p>Whether you have a question or a suggestion, we are always happy to listen to you.</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://discord.gg/Bykz6BAN8p" externalLink><i class="fab fa-discord"></i> Discord Channel</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://www.reddit.com/r/FastenHealth/" externalLink><i class="fab fa-reddit"></i> Reddit</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://docs.fastenhealth.com/" externalLink><i class="fas fa-book"></i> Documentation</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
</ngb-accordion>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-light" (click)="modal.close('Close click')">Close</button>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
|
@ -1,18 +1,37 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import {ActivatedRoute, NavigationStart, Router} from '@angular/router';
|
||||||
import {AuthService} from '../../services/auth.service';
|
import {AuthService} from '../../services/auth.service';
|
||||||
import {UserRegisteredClaims} from '../../models/fasten/user-registered-claims';
|
import {UserRegisteredClaims} from '../../models/fasten/user-registered-claims';
|
||||||
import {FastenApiService} from '../../services/fasten-api.service';
|
import {FastenApiService} from '../../services/fasten-api.service';
|
||||||
import {BackgroundJob} from '../../models/fasten/background-job';
|
import {BackgroundJob} from '../../models/fasten/background-job';
|
||||||
|
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import {SupportRequest} from '../../models/fasten/support-request';
|
||||||
|
import {environment} from '../../../environments/environment';
|
||||||
|
import {versionInfo} from '../../../environments/versions';
|
||||||
|
import {Subscription} from 'rxjs';
|
||||||
|
import {ToastNotification, ToastType} from '../../models/fasten/toast';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-header',
|
selector: 'app-header',
|
||||||
templateUrl: './header.component.html',
|
templateUrl: './header.component.html',
|
||||||
styleUrls: ['./header.component.scss']
|
styleUrls: ['./header.component.scss']
|
||||||
})
|
})
|
||||||
export class HeaderComponent implements OnInit {
|
export class HeaderComponent implements OnInit, OnDestroy {
|
||||||
current_user_claims: UserRegisteredClaims
|
current_user_claims: UserRegisteredClaims
|
||||||
backgroundJobs: BackgroundJob[] = []
|
backgroundJobs: BackgroundJob[] = []
|
||||||
constructor(private authService: AuthService, private router: Router, private fastenApi: FastenApiService) { }
|
|
||||||
|
newSupportRequest: SupportRequest = null
|
||||||
|
loading: boolean = false
|
||||||
|
errorMsg: string = ""
|
||||||
|
submitSuccess: boolean = false
|
||||||
|
|
||||||
|
routerSubscription: Subscription = null
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private authService: AuthService,
|
||||||
|
private router: Router,
|
||||||
|
private fastenApi: FastenApiService,
|
||||||
|
private modalService: NgbModal) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
try {
|
try {
|
||||||
|
@ -21,11 +40,25 @@ export class HeaderComponent implements OnInit {
|
||||||
this.current_user_claims = new UserRegisteredClaims()
|
this.current_user_claims = new UserRegisteredClaims()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.fastenApi.getBackgroundJobs().subscribe((data) => {
|
this.fastenApi.getBackgroundJobs().subscribe((data) => {
|
||||||
this.backgroundJobs = data.filter((job) => {
|
this.backgroundJobs = data.filter((job) => {
|
||||||
return job.data?.checkpoint_data?.summary?.UpdatedResources?.length > 0
|
return job.data?.checkpoint_data?.summary?.UpdatedResources?.length > 0
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.resetSupportRequestForm()
|
||||||
|
this.routerSubscription = this.router.events.subscribe((event) => {
|
||||||
|
if (event instanceof NavigationStart) {
|
||||||
|
this.newSupportRequest.current_page = event.url.toString()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
if(this.routerSubscription){
|
||||||
|
this.routerSubscription.unsubscribe()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closeMenu(e) {
|
closeMenu(e) {
|
||||||
|
@ -42,4 +75,39 @@ export class HeaderComponent implements OnInit {
|
||||||
this.authService.Logout()
|
this.authService.Logout()
|
||||||
.then(() => this.router.navigate(['auth/signin']))
|
.then(() => this.router.navigate(['auth/signin']))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//support Form
|
||||||
|
|
||||||
|
openSupportForm(content) {
|
||||||
|
this.modalService.open(content, { size: 'lg' });
|
||||||
|
}
|
||||||
|
|
||||||
|
resetSupportRequestForm() {
|
||||||
|
this.submitSuccess = false
|
||||||
|
let newSupportRequest = new SupportRequest()
|
||||||
|
newSupportRequest.dist_type = environment.environment_desktop ? 'desktop' : 'docker'
|
||||||
|
newSupportRequest.flavor = environment.environment_name
|
||||||
|
newSupportRequest.version = versionInfo.version
|
||||||
|
newSupportRequest.current_page = this.router.url.toString()
|
||||||
|
|
||||||
|
this.newSupportRequest = newSupportRequest
|
||||||
|
}
|
||||||
|
submitSupportForm() {
|
||||||
|
console.log("submitting support form", this.newSupportRequest)
|
||||||
|
this.loading = false
|
||||||
|
|
||||||
|
this.fastenApi.supportRequest(this.newSupportRequest).subscribe((resp: any) => {
|
||||||
|
this.loading = false
|
||||||
|
console.log(resp);
|
||||||
|
this.submitSuccess = true
|
||||||
|
//show success toast? close modal?
|
||||||
|
},
|
||||||
|
(err)=>{
|
||||||
|
this.loading = false
|
||||||
|
console.error("an error occurred during support request submission",err)
|
||||||
|
this.errorMsg = err || "An error occurred while submitting your support request. Please try again later."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ import {ListOrganizationComponent} from './list-generic-resource/list-organizati
|
||||||
import {ListPractitionerComponent} from './list-generic-resource/list-practitioner.component'
|
import {ListPractitionerComponent} from './list-generic-resource/list-practitioner.component'
|
||||||
import {ListProcedureComponent} from './list-generic-resource/list-procedure.component'
|
import {ListProcedureComponent} from './list-generic-resource/list-procedure.component'
|
||||||
import {ListServiceRequestComponent} from './list-generic-resource/list-service-request.component';
|
import {ListServiceRequestComponent} from './list-generic-resource/list-service-request.component';
|
||||||
import {NgbCollapseModule, NgbModule, NgbDropdownModule} from '@ng-bootstrap/ng-bootstrap';
|
import {NgbCollapseModule, NgbModule, NgbDropdownModule, NgbAccordionModule} from '@ng-bootstrap/ng-bootstrap';
|
||||||
import {PipesModule} from '../pipes/pipes.module';
|
import {PipesModule} from '../pipes/pipes.module';
|
||||||
import {ResourceListOutletDirective} from './resource-list/resource-list-outlet.directive';
|
import {ResourceListOutletDirective} from './resource-list/resource-list-outlet.directive';
|
||||||
import {DirectivesModule} from '../directives/directives.module';
|
import {DirectivesModule} from '../directives/directives.module';
|
||||||
|
@ -91,6 +91,7 @@ import {DirectivesModule} from '../directives/directives.module';
|
||||||
NgbModule,
|
NgbModule,
|
||||||
NgbDropdownModule,
|
NgbDropdownModule,
|
||||||
NgbCollapseModule,
|
NgbCollapseModule,
|
||||||
|
NgbAccordionModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MomentModule,
|
MomentModule,
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
export class SupportRequest {
|
||||||
|
full_name: string
|
||||||
|
email: string
|
||||||
|
request_content: string
|
||||||
|
|
||||||
|
current_page: string
|
||||||
|
dist_type: 'desktop' | 'docker' | 'cloud'
|
||||||
|
flavor: string
|
||||||
|
version: string
|
||||||
|
arch: string
|
||||||
|
os: string
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import {DashboardWidgetQuery} from '../models/widget/dashboard-widget-query';
|
||||||
import {ResourceGraphResponse} from '../models/fasten/resource-graph-response';
|
import {ResourceGraphResponse} from '../models/fasten/resource-graph-response';
|
||||||
import { fetchEventSource } from '@microsoft/fetch-event-source';
|
import { fetchEventSource } from '@microsoft/fetch-event-source';
|
||||||
import {BackgroundJob} from '../models/fasten/background-job';
|
import {BackgroundJob} from '../models/fasten/background-job';
|
||||||
|
import {SupportRequest} from '../models/fasten/support-request';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
@ -292,4 +293,17 @@ export class FastenApiService {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
supportRequest(request: SupportRequest): Observable<any> {
|
||||||
|
return this._httpClient.post<any>(`${GetEndpointAbsolutePath(globalThis.location, environment.fasten_api_endpoint_base)}/support/request`, request)
|
||||||
|
.pipe(
|
||||||
|
map((response: ResponseWrapper) => {
|
||||||
|
console.log("Support request response", response)
|
||||||
|
// @ts-ignore
|
||||||
|
return {}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<title>fastenhealth</title>
|
<title>fastenhealth</title>
|
||||||
<!-- Fonts and icons -->
|
<!-- Fonts and icons -->
|
||||||
<link href="https://fonts.googleapis.com/css?family=Poppins:200,300,400,600,700,800" rel="stylesheet"/>
|
<link href="https://fonts.googleapis.com/css?family=Poppins:200,300,400,600,700,800" rel="stylesheet"/>
|
||||||
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet"/>
|
<link href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" rel="stylesheet"/>
|
||||||
<link href="https://cdn.hello.coop/css/hello-btn.css" rel="stylesheet"/>
|
<link href="https://cdn.hello.coop/css/hello-btn.css" rel="stylesheet"/>
|
||||||
<script src="https://cdn.hello.coop/js/hello-btn.js"></script>
|
<script src="https://cdn.hello.coop/js/hello-btn.js"></script>
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<title>fastenhealth</title>
|
<title>fastenhealth</title>
|
||||||
<!-- Fonts and icons -->
|
<!-- Fonts and icons -->
|
||||||
<link href="https://fonts.googleapis.com/css?family=Poppins:200,300,400,600,700,800" rel="stylesheet"/>
|
<link href="https://fonts.googleapis.com/css?family=Poppins:200,300,400,600,700,800" rel="stylesheet"/>
|
||||||
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet"/>
|
<link href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" rel="stylesheet"/>
|
||||||
<script src="./assets/js/asmcrypto-2.3.2.all.es5.min.js"></script>
|
<script src="./assets/js/asmcrypto-2.3.2.all.es5.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var baseHref = "/"
|
var baseHref = "/"
|
||||||
|
|
Loading…
Reference in New Issue