Skip to content

Commit

Permalink
Merge pull request #35 from rotirk20/development
Browse files Browse the repository at this point in the history
Users fetch & table component for dashboard
  • Loading branch information
rotirk20 authored Oct 20, 2024
2 parents 9d3e051 + b39e3cf commit 1056912
Show file tree
Hide file tree
Showing 47 changed files with 210 additions and 33 deletions.
2 changes: 2 additions & 0 deletions frontend/src/app/admin/admin-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LocationsComponent } from './pages/locations/locations.component';
import { DashboardComponent } from './pages/dashboard/dashboard.component';
import { SettingsComponent } from './pages/settings/settings.component';
import { authGuard } from '../shared/guards/auth.guard';
import { UsersComponent } from './pages/users/users.component';

const routes: Routes = [
{ path: '', component: DashboardLayoutComponent,
Expand All @@ -13,6 +14,7 @@ const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' }, // Redirect to dashboard
{ path: 'home', component: DashboardComponent },
{ path: 'lokacije', component: LocationsComponent },
{ path: 'korisnici', component: UsersComponent },
{ path: 'postavke', component: SettingsComponent },
]},
{ path: '**', redirectTo: '/dashboard/home' } // Redirect unknown routes to home
Expand Down
49 changes: 49 additions & 0 deletions frontend/src/app/admin/components/table/table.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<div class="block w-full overflow-x-auto pb-8">
<table class="items-center bg-white shadow-md w-full border-collapse ">
<thead>
<tr>
<th *ngFor="let column of columns"
class="px-6 bg-blueGray-50 text-blueGray-500 align-middle border border-solid border-blueGray-100 py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left">
{{column.label}}
</th>
</tr>
</thead>

<tbody>
<tr *ngFor="let row of data">
<td *ngFor="let column of columns" class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4">
<ng-container *ngIf="column.key !== 'actions'; else actionButtons">
{{ row[column.key] }}
</ng-container>
<!-- Action buttons template -->
<ng-template #actionButtons>
<div class="inline-flex items-center rounded-md shadow-sm">
<button class="text-white text-sm bg-green-600 hover:bg-green-500 border border-slate-200 rounded-l-lg font-medium px-4 py-2 inline-flex space-x-1 items-center">
<span><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
</svg>
</span>
</button>
<button class="text-white bg-blue-600 text-sm hover:bg-blue-500 border-y border-slate-200 font-medium px-4 py-2 inline-flex space-x-1 items-center" *ngIf="viewAction">
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
</span>
</button>
<button class="text-white text-sm bg-red-600 hover:bg-red-500 border border-slate-200 rounded-r-lg font-medium px-4 py-2 inline-flex space-x-1 items-center">
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
</svg>
</span>
</button>
</div>
</ng-template>
</td>
</tr>
</tbody>

</table>
</div>
23 changes: 23 additions & 0 deletions frontend/src/app/admin/components/table/table.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TableComponent } from './table.component';

describe('TableComponent', () => {
let component: TableComponent;
let fixture: ComponentFixture<TableComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TableComponent]
})
.compileComponents();

fixture = TestBed.createComponent(TableComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
20 changes: 20 additions & 0 deletions frontend/src/app/admin/components/table/table.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { NgFor, NgIf } from '@angular/common';
import { Component, Input, OnInit } from '@angular/core';

@Component({
selector: 'app-table',
standalone: true,
imports: [NgFor, NgIf],
templateUrl: './table.component.html',
styleUrls: ['./table.component.scss']
})
export class TableComponent implements OnInit {
@Input() columns: any;
@Input() data: any;
@Input() viewAction: boolean = false;

ngOnInit(): void {
console.log(this.data);
console.log(this.columns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
</svg>
<span *ngIf="sidebarOpen" class="ml-2">Lokacije</span>
</a>
<a routerLink="/dashboard/korisnici" routerLinkActive="active-route"
class="flex items-center px-4 py-2 mt-2 text-gray-100 hover:bg-gray-700"
[ngClass]="{'opacity-100': sidebarOpen, 'opacity-0': !sidebarOpen, 'transition-opacity': true, 'duration-300': true}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M6 18L18 6M6 6l12 12" />
</svg>
<span *ngIf="sidebarOpen" class="ml-2">Korisnici</span>
</a>
<a routerLink="/dashboard/postavke" routerLinkActive="active-route"
class="flex items-center px-4 py-2 mt-2 text-gray-100 hover:bg-gray-700"
[ngClass]="{'opacity-100': sidebarOpen, 'opacity-0': !sidebarOpen, 'transition-opacity': true, 'duration-300': true}">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { SidebarComponent } from 'src/app/components/sidebar/sidebar.component';
import { SidebarComponent } from 'src/app/admin/components/sidebar/sidebar.component';

@Component({
selector: 'app-dashboard',
Expand Down
1 change: 1 addition & 0 deletions frontend/src/app/admin/pages/users/users.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<app-table [data]="users" [columns]="columns"></app-table>
23 changes: 23 additions & 0 deletions frontend/src/app/admin/pages/users/users.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { UsersComponent } from './users.component';

describe('UsersComponent', () => {
let component: UsersComponent;
let fixture: ComponentFixture<UsersComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [UsersComponent]
})
.compileComponents();

fixture = TestBed.createComponent(UsersComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
37 changes: 37 additions & 0 deletions frontend/src/app/admin/pages/users/users.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Component, OnInit } from '@angular/core';
import { TableComponent } from '../../components/table/table.component';
import { UserService } from 'src/app/shared/services/user.service';
import { User } from 'src/app/shared/models/user.model';

@Component({
selector: 'app-users',
standalone: true,
imports: [TableComponent],
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss']
})
export class UsersComponent implements OnInit {
users: User[] = [];
columns = [
{ key: 'id', label: 'ID' },
{ key: 'email', label: 'Email' },
{ key: 'username', label: 'Korisničko ime' },
{ key: 'actions', label: 'Akcije' }
];
constructor(private userService: UserService) {}

ngOnInit(): void {
this.getUsers();
}

getUsers() {
this.userService.getUsers().subscribe({
next: (users: User[]) => {
this.users = users;
console.log(users);
},
error: err => console.error('Observable emitted an error: ' + err),
complete: () => console.log('Observable emitted the complete notification')
});
}
}
4 changes: 2 additions & 2 deletions frontend/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { NavbarComponent } from './components/navbar/navbar.component';
import { FooterComponent } from './components/footer/footer.component';
import { NavbarComponent } from './home/components/navbar/navbar.component';
import { FooterComponent } from './home/components/footer/footer.component';

@Component({
selector: 'app-root',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component } from '@angular/core';
import {
ContactFormModel,
ContactFormErrors,
} from '../../../shared/models/contact-form.model';
} from '../../../../shared/models/contact-form.model';
import { FormsModule, NgForm } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { ContactService } from 'src/app/shared/services/contact.service';
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
display: flex;
align-items: center;
position: relative;
bottom: 5px;
}

.weather-icon {
Expand All @@ -13,7 +12,6 @@
.temperature {
font-size: 20px; /* Adjust font size as needed */
position: relative;
top: 3px;
}

.mr-2 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ export class WeatherWidget implements OnInit {
constructor(private weatherService: WeatherService) {}

ngOnInit(): void {
const basePath = 'https://openweathermap.org/img/wn/'; // Path to your PNG icons
// Start weather updates with a default interval of 15 minutes (can change dynamically)
this.weatherService.startWeatherUpdates(15 * 60 * 1000);

// Subscribe to the weather data observable
this.weatherService.weather$.subscribe(data => {
this.weatherData = data;
this.setWeatherIcon(data?.weather[0].main);
this.weatherIcon = basePath + data?.weather[0].icon + '.png';
});
}

Expand All @@ -32,25 +33,4 @@ export class WeatherWidget implements OnInit {
this.weatherService.stopWeatherUpdates();
}

setWeatherIcon(condition: string) {
// Set the icon path based on the weather condition
const basePath = 'assets/images/weather/'; // Path to your PNG icons
switch (condition) {
case 'Clear':
this.weatherIcon = `${basePath}sun.png`;
break;
case 'Clouds':
this.weatherIcon = `${basePath}cloud.png`;
break;
case 'Rain':
this.weatherIcon = `${basePath}cloud_rain.png`;
break;
case 'Snow':
this.weatherIcon = `${basePath}snow.png`;
break;
default:
this.weatherIcon = `${basePath}default.png`; // Default icon for unknown conditions
}
console.log(this.weatherIcon);
}
}
2 changes: 1 addition & 1 deletion frontend/src/app/home/pages/contact/contact.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { ContactFormComponent } from 'src/app/components/contact/contact-form/contact-form.component';
import { ContactFormComponent } from 'src/app/home/components/contact/contact-form/contact-form.component';

@Component({
selector: 'app-contact',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/home/pages/home/home.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="w-full">
<!-- Image Section -->
<div class="relative h-[500px] bg-cover bg-center" style="background-image: url('/assets/smetovi-bg.jpg');">
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center backdrop-blur-md">
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center backdrop-blur-sm">
<h1 class="text-white text-3xl md:text-5xl font-bold text-center uppercase">Dobro došli na Smetovi.ba</h1>
</div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="2 0 450 48" preserveAspectRatio="none"
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/home/pages/home/home.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HttpClientModule } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { RouterLink } from '@angular/router';
import { ItemListComponent } from 'src/app/components/item-list/item-list.component';
import { ItemListComponent } from 'src/app/home/components/item-list/item-list.component';
import { Location } from 'src/app/shared/models/location.model';
import { LocationService } from 'src/app/shared/services/location.service';
import { Title, Meta } from '@angular/platform-browser';
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/home/pages/location/location.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, ElementRef, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LocationCardComponent } from 'src/app/components/location-card/location-card.component';
import { LocationCardComponent } from 'src/app/home/components/location-card/location-card.component';
import { Location } from 'src/app/shared/models/location.model';
import { GoogleMapsModule, MapMarker, MapInfoWindow } from '@angular/google-maps';
import { InfoWindowContent } from 'src/app/shared/models/info-window.model';
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/shared/models/user.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface User {
username?: string;
email: string;
password: string;
password?: string;
}
16 changes: 16 additions & 0 deletions frontend/src/app/shared/services/user.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { UserService } from './user.service';

describe('UserService', () => {
let service: UserService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(UserService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
18 changes: 18 additions & 0 deletions frontend/src/app/shared/services/user.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { environment } from 'src/environments/environment';
import { User } from '../models/user.model';

@Injectable({
providedIn: 'root'
})
export class UserService {
private apiUrl = environment.apiUrl;

constructor(private http: HttpClient) {}

getUsers(): Observable<User[]> {
return this.http.get<User[]>(this.apiUrl + '/auth/users');
}
}

0 comments on commit 1056912

Please sign in to comment.