@@ -8,7 +8,7 @@ import { TableComponent } from './dashboard/table/table.component'; | |||
import { LoginComponent } from './login/login.component'; | |||
const routes: Routes = [ | |||
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' }, | |||
{ path: '', redirectTo: 'login', pathMatch: 'full' }, | |||
{ path: 'login', component: LoginComponent }, | |||
{ path: 'dashboard', component: DashboardComponent, children: [ | |||
{ | |||
@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core'; | |||
import { BrowserModule } from '@angular/platform-browser'; | |||
import { NgxEchartsModule } from 'ngx-echarts'; | |||
import { AppRoutingModule } from './app-routing.module'; | |||
import { HttpClientModule } from '@angular/common/http'; | |||
import { AppComponent } from './app.component'; | |||
import { LoginComponent } from './login/login.component'; | |||
@@ -12,6 +13,8 @@ import { TableComponent } from './dashboard/table/table.component'; | |||
import { ReportComponent } from './dashboard/report/report.component'; | |||
import { SettingsComponent } from './dashboard/settings/settings.component'; | |||
import { PartnerProfileService } from './services/partner-profile.service'; | |||
@NgModule({ | |||
declarations: [ | |||
AppComponent, | |||
@@ -26,11 +29,14 @@ import { SettingsComponent } from './dashboard/settings/settings.component'; | |||
BrowserModule, | |||
AppRoutingModule, | |||
BrowserAnimationsModule, | |||
HttpClientModule, | |||
NgxEchartsModule.forRoot({ | |||
echarts: () => import('echarts'), | |||
}), | |||
], | |||
providers: [], | |||
providers: [ | |||
PartnerProfileService, | |||
], | |||
bootstrap: [AppComponent] | |||
}) | |||
export class AppModule { } |
@@ -9,6 +9,7 @@ | |||
<a [ngClass]="{'active' : currentURL.includes('partners')}" [routerLink]="'partners'"> <img src="assets/database.svg" alt=""> <span> All Partners </span> </a> | |||
<a [ngClass]="{'active' : currentURL.includes('report')}" [routerLink]="'report'"> <img src="assets/report.svg" alt=""> <span> Report </span> </a> | |||
<a [ngClass]="{'active' : currentURL.includes('settings')}" [routerLink]="'settings'"> <img src="assets/settings.svg" alt=""> <span> Settings </span> </a> | |||
<a [routerLink]="'/login'"> <img src="assets/logout.svg" alt=""> <span> Logout </span> </a> | |||
</nav> | |||
</section> | |||
@@ -1,5 +1,6 @@ | |||
import { Component, OnInit } from '@angular/core'; | |||
import { NavigationEnd, Router } from '@angular/router'; | |||
import { PartnerProfileService } from '../services/partner-profile.service'; | |||
@Component({ | |||
selector: 'app-dashboard', | |||
@@ -10,7 +11,8 @@ export class DashboardComponent implements OnInit { | |||
currentURL: string = ''; | |||
constructor( | |||
private router: Router | |||
private router: Router, | |||
private partnerProfileService: PartnerProfileService | |||
) { } | |||
ngOnInit(): void { | |||
@@ -22,5 +24,9 @@ export class DashboardComponent implements OnInit { | |||
this.currentURL = val.url; | |||
} | |||
}); | |||
this.partnerProfileService.getPartnersData().then(data => { | |||
console.log(data); | |||
}) | |||
} | |||
} |
@@ -6,85 +6,50 @@ | |||
<div class="card"> | |||
<div class="table-actions"> | |||
<div class="input-holder"> | |||
<div class="input-holder side-label"> | |||
<input type="text" placeholder="Partner name, location, PRA user, contact..."> | |||
<label> Search </label> | |||
</div> | |||
<button> Export </button> | |||
<button> Filter </button> | |||
<button class="button"> <img src="assets/export.svg" alt=""> Export </button> | |||
<button class="button"> <img src="assets/filter.svg" alt=""> Filter </button> | |||
</div> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th>ID</th> | |||
<th>First name</th> | |||
<th>Last name</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<td>1</td> | |||
<td>Foo</td> | |||
<td>Bar</td> | |||
</tr> | |||
<tr> | |||
<td>2</td> | |||
<td>Someone</td> | |||
<td>Youknow</td> | |||
</tr> | |||
<tr> | |||
<td>3</td> | |||
<td>Iamout</td> | |||
<td>Ofinspiration</td> | |||
</tr> | |||
<tr> | |||
<td>4</td> | |||
<td>Yoda</td> | |||
<td>Skywalker</td> | |||
</tr> | |||
<tr> | |||
<td>5</td> | |||
<td>Patrick</td> | |||
<td>Dupont</td> | |||
</tr> | |||
<tr> | |||
<td>6</td> | |||
<td>Barack</td> | |||
<td>Obama</td> | |||
</tr> | |||
<tr> | |||
<td>7</td> | |||
<td>François</td> | |||
<td>Holland</td> | |||
</tr> | |||
<tr> | |||
<td>8</td> | |||
<td>Michel</td> | |||
<td>Popo</td> | |||
</tr> | |||
<tr> | |||
<td>9</td> | |||
<td>Chuck</td> | |||
<td>Norris</td> | |||
</tr> | |||
<tr> | |||
<td>10</td> | |||
<td>Simon</td> | |||
<td>Robin</td> | |||
</tr> | |||
<tr> | |||
<td>11</td> | |||
<td>Louis</td> | |||
<td>Lin</td> | |||
</tr> | |||
<tr> | |||
<td>12</td> | |||
<td>Zelda</td> | |||
<td>Link</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
<section class="table"> | |||
<header> | |||
<div class="col"> Select </div> | |||
<div class="col"> Name </div> | |||
<div class="col"> Primary Disctrict & State </div> | |||
<div class="col"> Type </div> | |||
<div class="col"> Total Reach </div> | |||
<div class="col"> Website </div> | |||
<div class="col"> Primary Contact </div> | |||
</header> | |||
<section class="data"> | |||
<div class="row" *ngFor="let partner of userData"> | |||
<div class="col"> <input type="checkbox"> </div> | |||
<div class="col"> | |||
{{ partner.organizationBasicInfo.name }} | |||
</div> | |||
<div class="col"> | |||
{{ partner.detailedProfile.district }}, {{ partner.detailedProfile.state }} | |||
</div> | |||
<div class="col"> | |||
{{ partner.organizationBasicInfo.type }} | |||
</div> | |||
<div class="col"> | |||
{{ partner.detailedProfile.totalReachOfOrganization }} | |||
</div> | |||
<div class="col"> | |||
<a target="_blank" [href]="partner.organizationBasicInfo.website">{{ partner.organizationBasicInfo.website }}</a> | |||
</div> | |||
<div class="col"> | |||
<div> {{ partner.primaryContact.name }} </div> | |||
<a href="mailTo:{{partner.primaryContact.email}}"> {{ partner.primaryContact.email }} </a> | |||
<a href="tel:{{partner.primaryContact.contactNumber}}"> {{ partner.primaryContact.contactNumber }} </a> | |||
</div> | |||
</div> | |||
</section> | |||
</section> | |||
<section class="page-settings"> | |||
<div class="input-holder side-label"> | |||
@@ -0,0 +1,98 @@ | |||
.table-actions { | |||
display: flex; | |||
align-items: center; | |||
justify-content: flex-end; | |||
margin-bottom: 10px; | |||
.input-holder { | |||
margin: 0; | |||
width: 30%; | |||
margin-right: auto; | |||
} | |||
button { | |||
border: 2px solid var(--input-border); | |||
padding: 7px 20px; | |||
border-radius: var(--common-border-radius); | |||
background-color: white; | |||
margin-left: 20px; | |||
color: var(--secondary-text); | |||
font-weight: 500; | |||
img { | |||
vertical-align: middle; | |||
width: 15px; | |||
height: 15px; | |||
} | |||
} | |||
} | |||
.table { | |||
height: 50vh; | |||
overflow: auto; | |||
line-height: 1.8; | |||
header, .row { | |||
display: flex; | |||
flex-wrap: nowrap; | |||
align-items: center; | |||
padding: 0 10px; | |||
.col { | |||
width: calc(100% / 7); | |||
font-size: 14px; | |||
p, a, &>div { | |||
display: block; | |||
white-space: nowrap; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
width: 100%; | |||
} | |||
&:nth-child(1) { | |||
width: 70px; | |||
} | |||
&:nth-child(3) { | |||
flex-grow: 1; | |||
} | |||
&:nth-child(5) { | |||
width: 100px; | |||
} | |||
} | |||
} | |||
header { | |||
background-color: var(--secondary-text); | |||
color: white; | |||
border-radius: var(--common-border-radius); | |||
position: sticky; | |||
z-index: 1; | |||
top: 0; | |||
height: 50px; | |||
} | |||
.row { | |||
color: var(--secondary-text); | |||
background-color: white; | |||
border-radius: var(--common-border-radius); | |||
cursor: pointer; | |||
transition: background-color 0.3s, color 0.3s; | |||
&:nth-child(even) { | |||
background-color: var(--input-background); | |||
} | |||
&:hover { | |||
background-color: var(--primary); | |||
color: white; | |||
a { | |||
color: var(--secondary); | |||
} | |||
} | |||
} | |||
} |
@@ -1,15 +1,22 @@ | |||
import { Component, OnInit } from '@angular/core'; | |||
import { PartnerProfileService } from '../../services/partner-profile.service'; | |||
@Component({ | |||
selector: 'app-table', | |||
templateUrl: './table.component.html', | |||
styleUrls: ['./table.component.scss'] | |||
selector: 'app-table', | |||
templateUrl: './table.component.html', | |||
styleUrls: ['./table.component.scss'] | |||
}) | |||
export class TableComponent implements OnInit { | |||
userData: Array<any> = []; | |||
constructor() { } | |||
constructor( | |||
private partnerProfileService: PartnerProfileService | |||
) { } | |||
ngOnInit(): void { | |||
} | |||
ngOnInit(): void { | |||
this.partnerProfileService.getPartnersData().then((data: any) => { | |||
this.userData = data; | |||
}, (e) => console.log(e)); | |||
} | |||
} |
@@ -16,7 +16,7 @@ export class LoginComponent implements OnInit { | |||
} | |||
authenticateUser() { | |||
this.router.navigate(['/dashboard']); | |||
this.router.navigate(['/dashboard/analytics']); | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
import { TestBed } from '@angular/core/testing'; | |||
import { PartnerProfileService } from './partner-profile.service'; | |||
describe('PartnerProfileService', () => { | |||
let service: PartnerProfileService; | |||
beforeEach(() => { | |||
TestBed.configureTestingModule({}); | |||
service = TestBed.inject(PartnerProfileService); | |||
}); | |||
it('should be created', () => { | |||
expect(service).toBeTruthy(); | |||
}); | |||
}); |
@@ -0,0 +1,18 @@ | |||
import { Injectable } from '@angular/core'; | |||
import { HttpClient } from '@angular/common/http'; | |||
import { lastValueFrom } from 'rxjs'; | |||
@Injectable({ | |||
providedIn: 'root' | |||
}) | |||
export class PartnerProfileService { | |||
constructor( | |||
private http: HttpClient | |||
) { } | |||
async getPartnersData() { | |||
return lastValueFrom(this.http.get('http://143.110.247.94/user-data/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2MjAyY2I3YmQwMWMxMzRhYjdjZmViOGUiLCJleHAiOjE2NDk0NjI0MDAsImlhdCI6MTY0NDM1MTEwMH0.MghrYB51zg5Qk2fk1yx9NO1nPLpdhwMK69XIuFrmrAY')); | |||
} | |||
} |
@@ -0,0 +1 @@ | |||
<svg fill="#7b7b7b" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M15 15H2V6h2.595s.689-.896 2.17-2H1a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h15a1 1 0 0 0 1-1v-3.746l-2 1.645V15zm-1.639-6.95v3.551L20 6.4l-6.639-4.999v3.131C5.3 4.532 5.3 12.5 5.3 12.5c2.282-3.748 3.686-4.45 8.061-4.45z"/></svg> |
@@ -0,0 +1,40 @@ | |||
<?xml version="1.0" encoding="iso-8859-1"?> | |||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |||
<svg fill="#7b7b7b" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||
viewBox="0 0 472.615 472.615" style="enable-background:new 0 0 472.615 472.615;" xml:space="preserve"> | |||
<g> | |||
<g> | |||
<polygon points="472.615,12.908 0,12.908 180.081,202.629 180.066,459.708 292.55,401.525 292.534,202.629 "/> | |||
</g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
</svg> |
@@ -0,0 +1,53 @@ | |||
<?xml version="1.0" encoding="iso-8859-1"?> | |||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | |||
<svg fill="white" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||
width="46.782px" height="46.782px" viewBox="0 0 46.782 46.782" style="enable-background:new 0 0 46.782 46.782;" | |||
xml:space="preserve"> | |||
<g> | |||
<g> | |||
<path d="M46.629,33.693l-1.262-2.219c-0.204-0.358-0.709-0.651-1.121-0.651L27.75,30.825c-0.412,0-0.979-0.25-1.256-0.555 | |||
l-0.985-1.08c-0.278-0.305-0.844-0.554-1.256-0.554h-5.604l-0.231-2.796c-0.347-2.177-2.387-3.554-4.535-3.072l-9.977,2.247 | |||
c-2.148,0.483-3.904,2.669-3.903,4.871L0,38.807c0,2.194,1.758,4.386,3.903,4.873l9.979,2.245 | |||
c2.148,0.482,4.188-0.896,4.535-3.075l0.231-2.792l0,0l3.609-0.001c0.412,0,0.978-0.25,1.255-0.556l0.984-1.078 | |||
c0.277-0.305,0.843-0.555,1.255-0.555h1.163c0.412,0,0.9-0.302,1.084-0.672l0.154-0.313c0.185-0.37,0.673-0.673,1.084-0.673h0.705 | |||
c0.412,0,0.836,0.326,0.94,0.726l0.056,0.208c0.105,0.398,0.514,0.725,0.904,0.725s0.862-0.302,1.047-0.672l0.155-0.314 | |||
c0.185-0.37,0.671-0.672,1.083-0.672h0.705c0.412,0,0.835,0.326,0.939,0.726l0.055,0.208c0.104,0.398,0.527,0.727,0.939,0.727 | |||
h7.478c0.411,0,0.917-0.293,1.12-0.652l1.263-2.219C46.833,34.639,46.833,34.052,46.629,33.693z M6.883,40.389 | |||
c-1.857,0-3.357-2.705-3.357-6.042c0-3.338,1.5-6.043,3.357-6.043c1.855,0,3.356,2.705,3.356,6.043 | |||
C10.239,37.684,8.738,40.389,6.883,40.389z"/> | |||
<polygon points="17.709,21.248 23.5,15.458 29.291,21.248 33.744,16.794 27.953,11.006 33.744,5.214 29.291,0.761 23.5,6.553 | |||
17.709,0.761 13.256,5.214 19.048,11.006 13.256,16.794 "/> | |||
</g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
<g> | |||
</g> | |||
</svg> |
@@ -68,9 +68,16 @@ | |||
&:focus { | |||
border: 2px solid var(--primary); | |||
border-radius: var(--common-border-radius); | |||
border-bottom-left-radius: 0px; | |||
border-top-left-radius: 0px; | |||
border-left: 0px; | |||
& + label { | |||
border: 2px solid transparent; | |||
border: 2px solid var(--primary); | |||
border-radius: var(--common-border-radius); | |||
border-top-right-radius: 0px; | |||
border-bottom-right-radius: 0px; | |||
border-right: 0px; | |||
} | |||
} | |||
} | |||