diff --git a/README.md b/README.md
index 8b25e14..6c89247 100644
--- a/README.md
+++ b/README.md
@@ -20,3 +20,7 @@ npm install
npm start
```
Ezután a http://localhost:3000/ cimen érhető el az oldal.
+
+## Használat
+* Felhasználónév: admin
+* Jelszó: admin123
diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts
new file mode 100644
index 0000000..a462469
--- /dev/null
+++ b/client/src/app/app-routing.module.ts
@@ -0,0 +1,38 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { AuthCheck } from './auth-check';
+import { ProductListComponent } from './product-list/product-list.component';
+import { LoginComponent } from './login/login.component';
+import { UserListComponent } from './user-list/user-list.component';
+
+const routes: Routes = [
+ {
+ path: '',
+ canActivate: [AuthCheck],
+ children: [
+ {
+ path: 'users',
+ component: UserListComponent
+ },
+ {
+ path: '',
+ component: ProductListComponent
+ }
+ ]
+ },
+ {
+ path: '',
+ children: [
+ {path: '', component: LoginComponent}
+ ]
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forRoot(routes)],
+ exports: [RouterModule]
+})
+export class AppRoutingModule {
+}
+
+export type RouteData = { title: string; };
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index f6842f4..7d16ecd 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -13,9 +13,12 @@
-
+
-
Termékek
-
+
+
+
+
+
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index a1bea9e..294d699 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -14,7 +14,9 @@ export class AppComponent implements OnInit {
password: new FormControl()
});
- constructor(public userService: UserService, private router: Router) {
+ toggle = false;
+
+ constructor(public userService: UserService, public router: Router) {
}
ngOnInit() {
@@ -31,4 +33,7 @@ export class AppComponent implements OnInit {
alert("Hiba: " + (e?.error?.error ?? JSON.stringify(e)));
}
}
+
+ async doRegister() {
+ }
}
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index 93db176..4ab8b34 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -12,11 +12,20 @@ import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { HttpClientModule } from '@angular/common/http';
+import { AppRoutingModule } from './app-routing.module';
+import { LoginComponent } from './login/login.component';
+import { UserListComponent } from './user-list/user-list.component';
+import { AuthCheck } from './auth-check';
+import { MatSlideToggleModule } from '@angular/material/slide-toggle';
+import { RegisterComponent } from './register/register.component';
@NgModule({
declarations: [
AppComponent,
- ProductListComponent
+ ProductListComponent,
+ LoginComponent,
+ UserListComponent,
+ RegisterComponent
],
imports: [
BrowserModule,
@@ -28,9 +37,13 @@ import { HttpClientModule } from '@angular/common/http';
MatTableModule,
MatPaginatorModule,
MatSortModule,
- HttpClientModule
+ HttpClientModule,
+ AppRoutingModule,
+ MatSlideToggleModule
+ ],
+ providers: [
+ AuthCheck
],
- providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
diff --git a/client/src/app/auth-check.ts b/client/src/app/auth-check.ts
new file mode 100644
index 0000000..6cc568c
--- /dev/null
+++ b/client/src/app/auth-check.ts
@@ -0,0 +1,13 @@
+import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
+import { Injectable } from '@angular/core';
+import { UserService } from './services/user.service';
+
+@Injectable()
+export class AuthCheck implements CanActivate {
+ constructor(private userService: UserService) {
+ }
+
+ canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
+ return !!this.userService.user;
+ }
+}
diff --git a/client/src/app/login/login.component.css b/client/src/app/login/login.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/client/src/app/login/login.component.html b/client/src/app/login/login.component.html
new file mode 100644
index 0000000..ef9f337
--- /dev/null
+++ b/client/src/app/login/login.component.html
@@ -0,0 +1 @@
+Jelentkezz be
diff --git a/client/src/app/login/login.component.spec.ts b/client/src/app/login/login.component.spec.ts
new file mode 100644
index 0000000..360f9f2
--- /dev/null
+++ b/client/src/app/login/login.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LoginComponent } from './login.component';
+
+describe('LoginComponent', () => {
+ let component: LoginComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [LoginComponent]
+ });
+ fixture = TestBed.createComponent(LoginComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/client/src/app/login/login.component.ts b/client/src/app/login/login.component.ts
new file mode 100644
index 0000000..80a60e8
--- /dev/null
+++ b/client/src/app/login/login.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-login',
+ templateUrl: './login.component.html',
+ styleUrls: ['./login.component.css']
+})
+export class LoginComponent {
+
+}
diff --git a/client/src/app/model/product.model.ts b/client/src/app/model/product.model.ts
new file mode 100644
index 0000000..1cb3a2a
--- /dev/null
+++ b/client/src/app/model/product.model.ts
@@ -0,0 +1,6 @@
+export interface Product {
+ name: string;
+ price: number;
+ description: string;
+ id: string;
+}
diff --git a/client/src/app/product-list/product-list-datasource.ts b/client/src/app/product-list/product-list-datasource.ts
deleted file mode 100644
index 79e2eb8..0000000
--- a/client/src/app/product-list/product-list-datasource.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-import { DataSource } from '@angular/cdk/collections';
-import { MatPaginator } from '@angular/material/paginator';
-import { MatSort } from '@angular/material/sort';
-import { map } from 'rxjs/operators';
-import { Observable, of as observableOf, merge } from 'rxjs';
-
-// TODO: Replace this with your own data model type
-export interface ProductListItem {
- name: string;
- id: number;
-}
-
-// TODO: replace this with real data from your application
-const EXAMPLE_DATA: ProductListItem[] = [
- {id: 1, name: 'Hydrogen'},
- {id: 2, name: 'Helium'},
- {id: 3, name: 'Lithium'},
- {id: 4, name: 'Beryllium'},
- {id: 5, name: 'Boron'},
- {id: 6, name: 'Carbon'},
- {id: 7, name: 'Nitrogen'},
- {id: 8, name: 'Oxygen'},
- {id: 9, name: 'Fluorine'},
- {id: 10, name: 'Neon'},
- {id: 11, name: 'Sodium'},
- {id: 12, name: 'Magnesium'},
- {id: 13, name: 'Aluminum'},
- {id: 14, name: 'Silicon'},
- {id: 15, name: 'Phosphorus'},
- {id: 16, name: 'Sulfur'},
- {id: 17, name: 'Chlorine'},
- {id: 18, name: 'Argon'},
- {id: 19, name: 'Potassium'},
- {id: 20, name: 'Calcium'},
-];
-
-/**
- * Data source for the ProductList view. This class should
- * encapsulate all logic for fetching and manipulating the displayed data
- * (including sorting, pagination, and filtering).
- */
-export class ProductListDataSource extends DataSource {
- data: ProductListItem[] = EXAMPLE_DATA;
- paginator: MatPaginator | undefined;
- sort: MatSort | undefined;
-
- constructor() {
- super();
- }
-
- /**
- * Connect this data source to the table. The table will only update when
- * the returned stream emits new items.
- * @returns A stream of the items to be rendered.
- */
- connect(): Observable {
- if (this.paginator && this.sort) {
- // Combine everything that affects the rendered data into one update
- // stream for the data-table to consume.
- return merge(observableOf(this.data), this.paginator.page, this.sort.sortChange)
- .pipe(map(() => {
- return this.getPagedData(this.getSortedData([...this.data ]));
- }));
- } else {
- throw Error('Please set the paginator and sort on the data source before connecting.');
- }
- }
-
- /**
- * Called when the table is being destroyed. Use this function, to clean up
- * any open connections or free any held resources that were set up during connect.
- */
- disconnect(): void {}
-
- /**
- * Paginate the data (client-side). If you're using server-side pagination,
- * this would be replaced by requesting the appropriate data from the server.
- */
- private getPagedData(data: ProductListItem[]): ProductListItem[] {
- if (this.paginator) {
- const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
- return data.splice(startIndex, this.paginator.pageSize);
- } else {
- return data;
- }
- }
-
- /**
- * Sort the data (client-side). If you're using server-side sorting,
- * this would be replaced by requesting the appropriate data from the server.
- */
- private getSortedData(data: ProductListItem[]): ProductListItem[] {
- if (!this.sort || !this.sort.active || this.sort.direction === '') {
- return data;
- }
-
- return data.sort((a, b) => {
- const isAsc = this.sort?.direction === 'asc';
- switch (this.sort?.active) {
- case 'name': return compare(a.name, b.name, isAsc);
- case 'id': return compare(+a.id, +b.id, isAsc);
- default: return 0;
- }
- });
- }
-}
-
-/** Simple sort comparator for example ID/Name columns (for client-side sorting). */
-function compare(a: string | number, b: string | number, isAsc: boolean): number {
- return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
-}
diff --git a/client/src/app/product-list/product-list.component.html b/client/src/app/product-list/product-list.component.html
index de4cced..f950952 100644
--- a/client/src/app/product-list/product-list.component.html
+++ b/client/src/app/product-list/product-list.component.html
@@ -1,15 +1,18 @@
-
-
- Id |
- {{row.id}} |
+
+ Név |
+ {{row.name}} |
-
-
- Name |
- {{row.name}} |
+
+ Leirás |
+ {{row.description}} |
+
+
+
+ Ár |
+ {{row.price}} |
@@ -17,7 +20,7 @@
;
- dataSource: ProductListDataSource;
+ @ViewChild(MatTable) table!: MatTable;
+
+ products: Observable
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
- displayedColumns = ['id', 'name'];
+ displayedColumns = ['name', 'description', 'price'];
- constructor() {
- this.dataSource = new ProductListDataSource();
+ constructor(private service: ProductService) {
+ this.products = service.getList().pipe(map(value => value as Product[]));
}
ngAfterViewInit(): void {
- this.dataSource.sort = this.sort;
- this.dataSource.paginator = this.paginator;
- this.table.dataSource = this.dataSource;
+ this.table.dataSource = this.products;
}
}
diff --git a/client/src/app/register/register.component.css b/client/src/app/register/register.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/client/src/app/register/register.component.html b/client/src/app/register/register.component.html
new file mode 100644
index 0000000..6b0ba2e
--- /dev/null
+++ b/client/src/app/register/register.component.html
@@ -0,0 +1 @@
+register works!
diff --git a/client/src/app/register/register.component.spec.ts b/client/src/app/register/register.component.spec.ts
new file mode 100644
index 0000000..9c4c73c
--- /dev/null
+++ b/client/src/app/register/register.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RegisterComponent } from './register.component';
+
+describe('RegisterComponent', () => {
+ let component: RegisterComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [RegisterComponent]
+ });
+ fixture = TestBed.createComponent(RegisterComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/client/src/app/register/register.component.ts b/client/src/app/register/register.component.ts
new file mode 100644
index 0000000..21647df
--- /dev/null
+++ b/client/src/app/register/register.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-register',
+ templateUrl: './register.component.html',
+ styleUrls: ['./register.component.css']
+})
+export class RegisterComponent {
+
+}
diff --git a/client/src/app/services/product.service.ts b/client/src/app/services/product.service.ts
new file mode 100644
index 0000000..50d7c39
--- /dev/null
+++ b/client/src/app/services/product.service.ts
@@ -0,0 +1,13 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ProductService {
+ constructor(private http: HttpClient) { }
+
+ getList() {
+ return this.http.get('/api/products')
+ }
+}
diff --git a/client/src/app/services/user.service.ts b/client/src/app/services/user.service.ts
index d2d67d2..b8ca3de 100644
--- a/client/src/app/services/user.service.ts
+++ b/client/src/app/services/user.service.ts
@@ -32,4 +32,8 @@ export class UserService {
this._user = undefined;
}
}
+
+ getList() {
+ return this.http.get('/api/users')
+ }
}
diff --git a/client/src/app/user-list/user-list.component.css b/client/src/app/user-list/user-list.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/client/src/app/user-list/user-list.component.html b/client/src/app/user-list/user-list.component.html
new file mode 100644
index 0000000..0db22af
--- /dev/null
+++ b/client/src/app/user-list/user-list.component.html
@@ -0,0 +1,29 @@
+
+
+
+ Felhasználónév |
+ {{row.username}} |
+
+
+
+ Hozzáférési szint |
+ {{row.accessLevel}} |
+
+
+
+ Születési dátum |
+ {{row.birthdate | date}} |
+
+
+
+
+
+
+
+
+
diff --git a/client/src/app/user-list/user-list.component.spec.ts b/client/src/app/user-list/user-list.component.spec.ts
new file mode 100644
index 0000000..88251ff
--- /dev/null
+++ b/client/src/app/user-list/user-list.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UserListComponent } from './user-list.component';
+
+describe('UserListComponent', () => {
+ let component: UserListComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [UserListComponent]
+ });
+ fixture = TestBed.createComponent(UserListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/client/src/app/user-list/user-list.component.ts b/client/src/app/user-list/user-list.component.ts
new file mode 100644
index 0000000..b95f5d2
--- /dev/null
+++ b/client/src/app/user-list/user-list.component.ts
@@ -0,0 +1,32 @@
+import { AfterViewInit, Component, ViewChild } from '@angular/core';
+import { MatTable } from '@angular/material/table';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import { UserService } from '../services/user.service';
+import { User } from '../model/user.model';
+import { map } from 'rxjs/operators';
+import { Observable } from 'rxjs';
+
+@Component({
+ selector: 'app-user-list',
+ templateUrl: './user-list.component.html',
+ styleUrls: ['./user-list.component.css']
+})
+export class UserListComponent implements AfterViewInit {
+ @ViewChild(MatPaginator) paginator!: MatPaginator;
+ @ViewChild(MatSort) sort!: MatSort;
+ @ViewChild(MatTable) table!: MatTable;
+
+ users: Observable
+
+ /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
+ displayedColumns = ['username', 'accessLevel', 'birthdate'];
+
+ constructor(private service: UserService) {
+ this.users = service.getList().pipe(map(value => value as User[]));
+ }
+
+ ngAfterViewInit(): void {
+ this.table.dataSource = this.users;
+ }
+}
diff --git a/server/index.js b/server/index.js
index 2dac319..59e53d0 100644
--- a/server/index.js
+++ b/server/index.js
@@ -58,6 +58,13 @@ app.use(passport.session({}));
app.use('/api/users', require('./usersRouter'))
app.use('/api/products', require('./productsRouter'))
+app.use(function (req, _, next) {
+ if (!req.url.startsWith('/api') && req.url.indexOf('.') === -1) {
+ req.url = '/';
+ }
+ next();
+})
+
app.use('', express.static('public'))
app.listen(3000, () => {
diff --git a/server/productsRouter.js b/server/productsRouter.js
index d59366b..852f269 100644
--- a/server/productsRouter.js
+++ b/server/productsRouter.js
@@ -29,7 +29,7 @@ router.get('/', async (req, res) => {
}
try {
const products = await Product.find();
- res.status(200).json(products);
+ res.status(200).json(products.map(product => getProductData(product)));
} catch (error) {
res.status(500).json({ message: error.message });
}
@@ -40,7 +40,7 @@ router.get('/:id', getProduct, (req, res) => {
if (!req.isAuthenticated()) {
return res.status(403).json({ message: "Unauthenticated" });
}
- res.json(res.product);
+ res.json(getProductData(res.product));
});
// POST /products - új termék létrehozása