first commit

This commit is contained in:
2024-01-19 11:09:11 +01:00
commit b18af7a943
29473 changed files with 4500547 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CommonModule } from '@angular/common';
import { UsersComponent } from './users/users.component';
import { UserComponent } from './user/user.component';
import { UserDetailComponent } from './user-detail/user-detail.component';
import { FormsModule } from '@angular/forms';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { UserService } from './services/user.service';
import { UserDataComponent } from './user-data/user-data.component';
const routes: Routes = [
{
path: 'users',
pathMatch:'full',
component : UsersComponent,
},
{
path:'',
pathMatch:'full',
redirectTo:'users',
},
{
path: 'users/new',
component: UserDetailComponent,
},
{
path: 'users/:id/edit',
component: UserDetailComponent,
},
{
path: 'users/:id',
component: UserDataComponent,
},
];
@NgModule({
declarations: [
UsersComponent,
UserComponent,
UserDetailComponent,
],
imports: [RouterModule.forRoot(routes),
FormsModule,
CommonModule,
FontAwesomeModule,
],
exports: [RouterModule]
})
export class AppRoutingModule { }

View File

View File

@@ -0,0 +1,13 @@
<div class="container-fluid">
<h1>Users Management System</h1>
<div class="row">
<div class="col-12">
<app-nav (onNewUser)="newUser()"></app-nav>
<router-outlet></router-outlet>
</div>
</div>
</div>

View File

@@ -0,0 +1,35 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'ums'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('ums');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, ums');
});
});

24
src/app/app.component.ts Normal file
View File

@@ -0,0 +1,24 @@
import { Component } from '@angular/core';
import { User } from './classes/user';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
showForm: boolean = false;
title = 'ums';
userSelected: User= new User;
updateUser(user:User){
this.showForm = true;
this.userSelected = user;
}
newUser(){
alert("ciao");
this.userSelected = new User();
this.showForm = true;
}
}

View File

@@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
AppModule,
ServerModule,
],
bootstrap: [AppComponent],
})
export class AppServerModule {}

28
src/app/app.module.ts Normal file
View File

@@ -0,0 +1,28 @@
import { NgModule } from '@angular/core';
import { BrowserModule, provideClientHydration } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavComponent } from './nav/nav.component';
import { UserDataComponent } from './user-data/user-data.component';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
NavComponent,
UserDataComponent,
],
imports: [
HttpClientModule,
BrowserModule,
AppRoutingModule,
],
providers: [
provideClientHydration(),
],
bootstrap: [AppComponent]
})
export class AppModule { }

26
src/app/classes/user.ts Normal file
View File

@@ -0,0 +1,26 @@
import { UserInterface } from "../interfaces/user";
export class User implements UserInterface{
id:number;
name: string;
lastname: string;
email: string;
fiscalcode: string;
province: string;
phone: string;
age: number;
constructor(){
this.id = 0;
this.name = '';
this.lastname = '';
this.email = '';
this.fiscalcode = '';
this.province = '';
this.phone = '';
this.age = 18;
}
}

View File

@@ -0,0 +1,10 @@
export interface UserInterface {
id:number
name: string;
lastname: string;
email: string;
fiscalcode: string;
province: string;
phone: string;
age: number;
}

View File

View File

@@ -0,0 +1,38 @@
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#" routerLink="/">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="#" routerLink="users">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item active">
<a href="#" class="nav-link" routerLink="users/new" >New User</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NavComponent } from './nav.component';
describe('NavComponent', () => {
let component: NavComponent;
let fixture: ComponentFixture<NavComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [NavComponent]
})
.compileComponents();
fixture = TestBed.createComponent(NavComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,20 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
@Component({
selector: 'app-nav',
templateUrl: './nav.component.html',
styleUrl: './nav.component.css'
})
export class NavComponent implements OnInit {
@Output() onNewUser = new EventEmitter()
constructor(){
}
ngOnInit(){
}
newUser(){
this.onNewUser.emit();
}
}

View File

@@ -0,0 +1,42 @@
import { Injectable } from "@angular/core";
import { User } from "../classes/user";
import { UserInterface } from "../interfaces/user";
import { HttpClient } from "@angular/common/http";
import {environment} from '../../environments/environment'
import { Observable } from "rxjs";
@Injectable({
providedIn: 'root'
})
export class UserService{
apiurl = environment.APIURL
constructor(private http:HttpClient){
}
getUsers(): Observable<User[]> {
return this.http.get<User []>(this.apiurl);
}
getUser(id: number): Observable<User> {
return this.http.get<User>(this.apiurl + '/' + id);
}
updateUser(user: UserInterface): Observable<User[]>{
return this.http.put<User[]>(this.apiurl + '/' + user.id, user);
}
deleteUser(user: User){
return this.http.delete<User[]>(this.apiurl + '/' + user.id);
}
createUser(user: UserInterface): Observable<User []>{
return this.http.post<User[]>(this.apiurl , user);
}
}

View File

@@ -0,0 +1 @@
<p>{{user | json}}</p>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { UserDataComponent } from './user-data.component';
describe('UserDataComponent', () => {
let component: UserDataComponent;
let fixture: ComponentFixture<UserDataComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [UserDataComponent]
})
.compileComponents();
fixture = TestBed.createComponent(UserDataComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,28 @@
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { UserService } from '../services/user.service';
import { Router } from 'express';
import { User } from '../classes/user';
import { UserInterface } from '../interfaces/user';
@Component({
selector: 'app-user-data',
templateUrl: './user-data.component.html',
styleUrl: './user-data.component.css'
})
export class UserDataComponent implements OnInit {
public user: UserInterface | undefined;
constructor(private userService: UserService, private route: ActivatedRoute){
}
ngOnInit(): void {
this.route.params.subscribe((param) => {
const id = Number(param['id']);
this.userService.getUser(id)
.subscribe(user=> this.user = user)
}
)
}
}

View File

@@ -0,0 +1,38 @@
<form class="userForm" #f="ngForm">
{{user|json}}
<input type="hidden" name="id" [(ngModel)]="user.id">
<div class="form-group">
<label for="firstname">First name</label>
<input class="form-control" [(ngModel)]="user.name" name="firstname" id="firstname">
</div>
<div class="form-group">
<label for="lastname">Last name</label>
<input class="form-control" [(ngModel)]="user.lastname" name="lastname" id="lastname">
</div>
<div class="form-group">
<label for="fiscalcode">Fiscal code</label>
<input class="form-control" [(ngModel)]="user.fiscalcode" name="fiscalcode" id="fiscalcode">
</div>
<div class="form-group">
<label for="email">Email</label>
<input class="form-control" [(ngModel)]="user.email" type="email" name="email" id="email">
</div>
<div class="form-group">
<label for="phone">Phone</label>
<input class="form-control" [(ngModel)]="user.phone" name="phone" id="phone">
</div>
<div class="form-group">
<label for="province">Province</label>
<input class="form-control" [(ngModel)]="user.province" name="province" id="province">
</div>
<div class="form-group">
<label for="age">Age</label>
<input class="form-control" [(ngModel)]="user.age" type="number" name="age" id="age">
</div>
<div class="form-group form-footer">
<button class="btn btn-outline-secondary" (click)="saveUser()">SAVE</button>
<button class="btn btn-success" (click)="resetForm(f.form)">RESET</button>
</div>
</form>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { UserDetailComponent } from './user-detail.component';
describe('UserDetailComponent', () => {
let component: UserDetailComponent;
let fixture: ComponentFixture<UserDetailComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [UserDetailComponent]
})
.compileComponents();
fixture = TestBed.createComponent(UserDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,76 @@
import { FormsModule } from '@angular/forms';
import { Component, Input, OnInit } from '@angular/core';
import { User } from '../classes/user';
import { UserService } from '../services/user.service';
import { createSecureServer } from 'node:http2';
import { ActivatedRoute } from '@angular/router';
import { Router } from '@angular/router';
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrl: './user-detail.component.css'
})
export class UserDetailComponent implements OnInit {
private usercopy= new User ;
private __user = new User;
@Input() set user(user: User){
this.__user = user;
this.usercopy=Object.assign({},user);
}
get user(){
return this.__user;
}
constructor( private userService:UserService, private route:ActivatedRoute, private router:Router){
}
ngOnInit(){
this.route.params.subscribe( param => {
const id = Number(param['id']);
this.userService.getUser(id)
.subscribe(user => this.user = user);
}
)
}
saveUser(){
alert(this.user.id)
if(this.user.id >0){
alert(this.user.id)
this.userService.updateUser(this.user);
}
else{
this.userService.createUser(this.user);
}
this.router.navigateByUrl('/users')
}
resetForm(form: { reset: () => void; }){
if(this.user.id === 0){
this.user = new User();
}
else{
this.user = this.usercopy
}
}
}

View File

View File

@@ -0,0 +1,17 @@
<td>{{user.name}}</td>
<td>{{user.lastname}}</td>
<td>{{user.fiscalcode}}</td>
<td>{{user.email}}</td>
<td>{{user.phone}}</td>
<td>{{user.province}}</td>
<td>{{user.age}}</td>
<td>
<div class="row">
<div class="col-sm-6"> <button class="btn btn-primary btn-sm" (click)="updateUser()"><fa-icon [icon]="faPen">ciao</fa-icon></button>
</div>
<div class="col-sm-6"> <button class="btn btn-primary btn-sm" routerLink="{{user.id}}"><fa-icon [icon]="faSearch"></fa-icon></button>
</div>
<div class="col-sm-6"> <button class="btn btn-danger btn-sm" (click)="deleteUser()"><fa-icon [icon]="faTrash"></fa-icon></button>
</div>
</div>
</td>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { UserComponent } from './user.component';
describe('UserComponent', () => {
let component: UserComponent;
let fixture: ComponentFixture<UserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [UserComponent]
})
.compileComponents();
fixture = TestBed.createComponent(UserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,53 @@
import { Component, Input, OnInit, Output } from '@angular/core';
import { UserService } from '../services/user.service';
import { EventEmitter } from "@angular/core";
import { EventManager } from '@angular/platform-browser';
import { ActivatedRoute, EventType } from '@angular/router';
import { User } from '../classes/user';
import { faPencilAlt, faTrash, faSearch } from '@fortawesome/free-solid-svg-icons';
import { Router } from '@angular/router';
@Component({
selector: 'tr[app-user]',
templateUrl: './user.component.html',
styleUrl: './user.component.css'
})
export class UserComponent implements OnInit {
@Input('user-data') user: User ;
@Output('onDeleteUser') userDeleted = new EventEmitter();
@Output('onSelectUser') userSelected = new EventEmitter();
faPen = faPencilAlt;
faTrash=faTrash;
faSearch=faSearch;
constructor(private userService:UserService, private route: Router){
this.user = {
id:0,
name: '',
lastname: '',
email: '',
fiscalcode: '',
province: '',
phone: '',
age: 0
}
}
ngOnInit(): void {
}
deleteUser(){
this.userDeleted.emit(this.user);
}
updateUser(){
this.route.navigateByUrl('/users/' + this.user.id + '/edit')
this.userSelected.emit(this.user);
}
}

View File

View File

@@ -0,0 +1,26 @@
<table class="table table-striped table-dark table-sm">
<caption>{{title}}</caption>
<thead>
<tr>
<th>Name</th>
<th>Last name</th>
<th>Fiscal code</th>
<th>Email</th>
<th>Phone</th>
<th>Province</th>
<th>Age</th>
<th>Actions</th>
</tr>
</thead>
<tbody *ngIf=" (users$ | async) as users">
<tr app-user *ngFor="let user of users" [user-data] = "user"
(onDeleteUser)="onDeleteUser($event)"
(onSelectUser)="onSelectUser($event)">
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,43 @@
import { Component, EventEmitter, OnInit, Output } from "@angular/core";
import { UserService } from "../services/user.service";
import { User } from "../classes/user";
import { Observable } from "rxjs";
@Component( {
selector: 'app-users',
template: `<h2>Users</h2>`,
templateUrl: 'users.component.html',
styleUrls: [
'users.component.css'
],
standalone: false
})
export class UsersComponent implements OnInit {
title='Users';
public users$:Observable<User[]> = this.service.getUsers();
@Output () updateUser = new EventEmitter<User>();
constructor(private service: UserService){
}
ngOnInit(){
}
onDeleteUser(user:User){
this.service.deleteUser(user);
}
onSelectUser(user:User){
const usercopy = Object.assign({},user)
this.updateUser.emit(usercopy);
}
}

0
src/assets/.gitkeep Normal file
View File

View File

@@ -0,0 +1,3 @@
export const environment = {
production:true
};

View File

@@ -0,0 +1,4 @@
export const environment = {
production: false,
APIURL: 'http://localhost:3000/users'
};

BIN
src/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

14
src/index.html Normal file
View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Ums</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="juve.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>

BIN
src/juve.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

1
src/main.server.ts Normal file
View File

@@ -0,0 +1 @@
export { AppServerModule as default } from './app/app.module.server';

7
src/main.ts Normal file
View File

@@ -0,0 +1,7 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

1
src/styles.css Normal file
View File

@@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */