diff --git a/client/src/app/app.component.css b/client/src/app/app.component.css
index e69de29..d2daae3 100644
--- a/client/src/app/app.component.css
+++ b/client/src/app/app.component.css
@@ -0,0 +1,14 @@
+.main{
+ align-items: center;
+ padding: 15px;
+ display: flex;
+ justify-content: center;
+ margin-bottom: 40px;
+ margin-top: 20px;
+}
+.main button{
+ padding: 10px;
+ font-size: 16px;
+ font-weight: 600;
+ border-radius: 10px;
+}
\ No newline at end of file
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index bf8f0fb..63bf361 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -1 +1,4 @@
-
das
\ No newline at end of file
+
+
+
+
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index 87aaf53..42d9a33 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -1,4 +1,6 @@
import { Component } from '@angular/core';
+import { UserModel } from './user.model';
+import { UserService } from './user.service';
@Component({
selector: 'app-root',
@@ -6,5 +8,19 @@ import { Component } from '@angular/core';
styleUrls: ['./app.component.css']
})
export class AppComponent {
- title = 'client';
+ userData: UserModel[] = [];
+ loadButton="Load Data";
+ showTable = false;
+
+ constructor(private userService: UserService) { }
+
+ onLoadData(){
+ this.loadButton = "Refresh data";
+ this.showTable = true;
+ this.userService.getUsers().subscribe(
+ responseData=>{
+ this.userData = responseData;
+ }
+ )
+ }
}
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index 8dfc1d6..a95b8ac 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -1,14 +1,24 @@
+import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
+import { ReactiveFormsModule} from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
+import { TabularComponent } from './tabular/tabular.component';
+import { UserAddComponent } from './tabular/user-add/user-add.component';
+import { DateformatPipe } from './tabular/dateformat.pipe';
@NgModule({
declarations: [
- AppComponent
+ AppComponent,
+ TabularComponent,
+ UserAddComponent,
+ DateformatPipe
],
imports: [
- BrowserModule
+ BrowserModule,
+ ReactiveFormsModule,
+ HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/client/src/app/tabular/dateformat.pipe.spec.ts b/client/src/app/tabular/dateformat.pipe.spec.ts
new file mode 100644
index 0000000..6cbc4e0
--- /dev/null
+++ b/client/src/app/tabular/dateformat.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { DateformatPipe } from './dateformat.pipe';
+
+describe('DateformatPipe', () => {
+ it('create an instance', () => {
+ const pipe = new DateformatPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/client/src/app/tabular/dateformat.pipe.ts b/client/src/app/tabular/dateformat.pipe.ts
new file mode 100644
index 0000000..a44aa29
--- /dev/null
+++ b/client/src/app/tabular/dateformat.pipe.ts
@@ -0,0 +1,13 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'dateformat'
+})
+export class DateformatPipe implements PipeTransform {
+
+ transform(value: string): string {
+ const date = new Date(value);
+ return date.getDate()+" "+date.toLocaleString('en-US', {month: 'long',})+" "+date.getFullYear()+" Time: "+date.getHours()+":"+date.getMinutes();
+ }
+
+}
diff --git a/client/src/app/tabular/tabular.component.css b/client/src/app/tabular/tabular.component.css
new file mode 100644
index 0000000..b7e0ce2
--- /dev/null
+++ b/client/src/app/tabular/tabular.component.css
@@ -0,0 +1,43 @@
+.table_tag{
+ display:revert;
+ width: 100%;
+ border: 2px solid;
+ border-radius: 10px;
+ border-color: darkgray;
+ padding: 5px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+ box-shadow: 2px 5px 2px gainsboro;
+ border-collapse: separate;
+ border-spacing: 0 1em;
+}
+.table_tag tr{
+ border-bottom: 2px solid;
+}
+.table_tag th{
+ font-size: 20px;
+ padding: 10px;
+ text-align: center;
+}
+.table_tag td{
+ text-align: center;
+ font-size: 1em;
+ /* box-sizing: border-box; */
+
+}
+td input{
+ height: 30px;
+ font-size: 1em;
+ background-color: white;
+
+}
+.btn{
+ margin-right: 10px;
+ background-color: dodgerblue !important;
+ color: white;
+ border-radius: 12px;
+}
+.btn-danger{
+ background-color: coral !important;
+ border-radius: 12px;
+}
\ No newline at end of file
diff --git a/client/src/app/tabular/tabular.component.html b/client/src/app/tabular/tabular.component.html
new file mode 100644
index 0000000..d44904b
--- /dev/null
+++ b/client/src/app/tabular/tabular.component.html
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file
diff --git a/client/src/app/tabular/tabular.component.spec.ts b/client/src/app/tabular/tabular.component.spec.ts
new file mode 100644
index 0000000..464c594
--- /dev/null
+++ b/client/src/app/tabular/tabular.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TabularComponent } from './tabular.component';
+
+describe('TabularComponent', () => {
+ let component: TabularComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ TabularComponent ]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(TabularComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/client/src/app/tabular/tabular.component.ts b/client/src/app/tabular/tabular.component.ts
new file mode 100644
index 0000000..81b5e99
--- /dev/null
+++ b/client/src/app/tabular/tabular.component.ts
@@ -0,0 +1,77 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { UserModel, columnName} from '../user.model';
+import { UserService } from '../user.service';
+
+@Component({
+ selector: 'app-tabular',
+ templateUrl: './tabular.component.html',
+ styleUrls: ['./tabular.component.css']
+})
+export class TabularComponent implements OnInit {
+ prevArray:string[] = [];
+ @Input ('userdata') userData:UserModel[];
+ saveEnable = false;
+ header = Object.values(columnName);
+
+ constructor(private userService: UserService) { }
+
+ ngOnInit(): void {
+ }
+
+ onUpdatedData(){
+ this.userService.getUsers().subscribe(newData=>{
+ this.userData = newData;
+ });
+ }
+
+ onEdit(event:any){
+ event.path[0].value = "Save";
+ event.path[1].childNodes[1].value = "Cancel";
+ for(let j=0;j{
+ this.userService.getUsers().subscribe(newData=>{
+ this.userData = newData;
+ });
+ });
+
+ }
+
+ onCancel(event:any){
+ this.saveEnable = false;
+ event.path[0].value = "Delete";
+ event.path[1].childNodes[0].value = "Edit";
+ let j:number=0;
+ for(j=0;j{
+ this.userService.getUsers().subscribe(newData=>{
+ this.userData = newData;
+ });
+ })
+ }
+
+
+}
diff --git a/client/src/app/tabular/user-add/user-add.component.css b/client/src/app/tabular/user-add/user-add.component.css
new file mode 100644
index 0000000..b9a0db9
--- /dev/null
+++ b/client/src/app/tabular/user-add/user-add.component.css
@@ -0,0 +1,25 @@
+.input_tag{
+ display: flex;
+ justify-content: space-around;
+ text-align: center;
+ font-size: 1em;
+ margin-bottom: 10px;
+}
+.input_tag input{
+ height: 30px;
+ font-size: 1em;
+ background-color: white;
+ border-color: #cbb3b3;
+ border-radius: 10px;
+}
+.btn{
+ padding: 10px;
+ padding-bottom: 25px;
+ background-color: dodgerblue !important;
+ color:white
+}
+.input_tag p{
+ margin-block-start:5px;
+ margin-block-end: 5px;
+ color: red;
+}
\ No newline at end of file
diff --git a/client/src/app/tabular/user-add/user-add.component.html b/client/src/app/tabular/user-add/user-add.component.html
new file mode 100644
index 0000000..ca208ed
--- /dev/null
+++ b/client/src/app/tabular/user-add/user-add.component.html
@@ -0,0 +1,37 @@
+
+
diff --git a/client/src/app/tabular/user-add/user-add.component.spec.ts b/client/src/app/tabular/user-add/user-add.component.spec.ts
new file mode 100644
index 0000000..7792570
--- /dev/null
+++ b/client/src/app/tabular/user-add/user-add.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UserAddComponent } from './user-add.component';
+
+describe('UserAddComponent', () => {
+ let component: UserAddComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ UserAddComponent ]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(UserAddComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/client/src/app/tabular/user-add/user-add.component.ts b/client/src/app/tabular/user-add/user-add.component.ts
new file mode 100644
index 0000000..0d749a5
--- /dev/null
+++ b/client/src/app/tabular/user-add/user-add.component.ts
@@ -0,0 +1,65 @@
+import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { UserService } from 'src/app/user.service';
+import { Role } from '../../user.model';
+
+@Component({
+ selector: 'app-user-add',
+ templateUrl: './user-add.component.html',
+ styleUrls: ['./user-add.component.css'],
+})
+export class UserAddComponent implements OnInit {
+ @Output() updatedData = new EventEmitter();
+ addUserForm: FormGroup;
+ addButtonClicked = false;
+ role = Role;
+
+ constructor(private userService: UserService) {}
+
+ ngOnInit(): void {
+ this.addUserForm = new FormGroup({
+ firstName: new FormControl(null, [Validators.required]),
+ middleName: new FormControl(null),
+ lastName: new FormControl(null, [Validators.required]),
+ email: new FormControl(null, [Validators.required, Validators.email]),
+ phoneNumber: new FormControl(null, [Validators.required]),
+ role: new FormControl(null, [
+ Validators.required,
+ this.forbiddenNames.bind(this),
+ ]),
+ address: new FormControl(null, [Validators.required]),
+ createdDate: new FormControl(null),
+ });
+ }
+
+ onSubmit() {
+ console.log(this.addUserForm);
+ if (this.addUserForm.status === 'INVALID') {
+ this.addButtonClicked = true;
+ return;
+ }
+ // else if(this.addUserForm.get('role')){
+
+ // }
+ else {
+ this.addButtonClicked = false;
+ this.addUserForm.patchValue({
+ createdDate: new Date(),
+ });
+ this.userService
+ .addUser(this.addUserForm.value)
+ .subscribe((responseData) => {
+ this.addUserForm.reset();
+ this.updatedData.emit();
+ });
+ }
+ }
+
+ forbiddenNames(control: FormControl): { [s: string]: boolean } | null {
+ if (control.value in this.role) {
+ return null;
+ } else {
+ return { roleIsForbidden: true };
+ }
+ }
+}
diff --git a/client/src/app/user.model.ts b/client/src/app/user.model.ts
new file mode 100644
index 0000000..233333b
--- /dev/null
+++ b/client/src/app/user.model.ts
@@ -0,0 +1,29 @@
+export interface UserModel{
+ userId?: string,
+ firstName: string,
+ middleName: string,
+ lastName: string,
+ email: string,
+ phoneNumber: number,
+ role: string,
+ address: string,
+ createdDate: string,
+}
+
+export enum Role {
+ superAdmin = "SuperAdmin",
+ Admin = "Admin",
+ Subscriber = "Subscriber"
+}
+
+export enum columnName{
+ firstName = 'First Name',
+ middleName = 'Middle Name',
+ lastName= 'Last Name',
+ email= 'Email',
+ phoneNumber = 'Phone Number',
+ role= 'Role',
+ address = 'Address',
+ createdDate = 'User Created Date',
+ edit = 'Edit'
+ }
\ No newline at end of file
diff --git a/client/src/app/user.service.spec.ts b/client/src/app/user.service.spec.ts
new file mode 100644
index 0000000..3f804c9
--- /dev/null
+++ b/client/src/app/user.service.spec.ts
@@ -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();
+ });
+});
diff --git a/client/src/app/user.service.ts b/client/src/app/user.service.ts
new file mode 100644
index 0000000..251bd4b
--- /dev/null
+++ b/client/src/app/user.service.ts
@@ -0,0 +1,40 @@
+import { Injectable } from '@angular/core';
+import {HttpClient} from '@angular/common/http';
+import {UserModel} from './user.model';
+import { map } from 'rxjs';
+import {environment} from '../environments/environment';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class UserService {
+
+ constructor(private http: HttpClient) { }
+
+ getUsers(){
+ return this.http.get<{[key: string]:UserModel}>(environment.apiURL).pipe(
+ map((responseData)=>{
+ const userArray:UserModel[] = [];
+ for (const key in responseData){
+ if(responseData.hasOwnProperty(key)){
+ userArray.push({...responseData[key]});
+ }
+ }
+ return userArray;
+ })
+ )
+ }
+
+ deleteUser(id:string){
+ return this.http.delete(`${environment.apiURL}/${id}`);
+ }
+
+ addUser(userData:UserModel){
+ return this.http.post(environment.apiURL,userData);
+ }
+
+ editUser(id:string,userData:{[key: string]: string}){
+ console.log(userData);
+ return this.http.put(`${environment.apiURL}/${id}`,userData);
+ }
+}
diff --git a/client/src/environments/environment.ts b/client/src/environments/environment.ts
index f56ff47..10e01a9 100644
--- a/client/src/environments/environment.ts
+++ b/client/src/environments/environment.ts
@@ -3,7 +3,8 @@
// The list of file replacements can be found in `angular.json`.
export const environment = {
- production: false
+ production: false,
+ apiURL: 'http://localhost:9010/users'
};
/*
diff --git a/client/src/styles.css b/client/src/styles.css
index 90d4ee0..4bf22ac 100644
--- a/client/src/styles.css
+++ b/client/src/styles.css
@@ -1 +1,4 @@
/* You can add global styles to this file, and also import other style files */
+body{
+ font-family: sans-serif;
+}
\ No newline at end of file
diff --git a/client/tsconfig.json b/client/tsconfig.json
index ff06eae..d01d793 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -21,7 +21,8 @@
"lib": [
"es2020",
"dom"
- ]
+ ],
+ "strictPropertyInitialization":false
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
diff --git a/server/package-lock.json b/server/package-lock.json
index cc1e58c..5aa1f07 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -5,6 +5,7 @@
"requires": true,
"packages": {
"": {
+ "name": "server",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
diff --git a/server/src/controller/user.ts b/server/src/controller/user.ts
index 62782fc..ba15ec6 100644
--- a/server/src/controller/user.ts
+++ b/server/src/controller/user.ts
@@ -14,7 +14,7 @@ export const getUserData = (req:any,res:any)=>{
export const deleteUser = (req:any,res:any)=>{
const {id} = req.params
- pool.query('DELETE FROM users WHERE user_id = $1',[id],(q_err:any,q_res:any)=>{
+ pool.query('DELETE FROM users WHERE userId = $1',[id],(q_err:any,q_res:any)=>{
if(q_err){
console.log(q_err);
res.code = 404
@@ -25,7 +25,7 @@ export const deleteUser = (req:any,res:any)=>{
}
export const createUser = (req:any,res:any)=>{
const data = [req.body.firstName,req.body.middleName,req.body.lastName,req.body.email,req.body.phoneNumber,req.body.role,req.body.address,req.body.createdDate];
- pool.query('insert into users (first_name,middle_name,last_name,email,phone_number,role,address,created_date) values ($1,$2,$3,$4,$5,$6,$7,$8)',data,(q_err:any,q_res:any)=>{
+ pool.query('insert into users (firstName,middleName,lastName,email,phoneNumber,role,address,createdDate) values ($1,$2,$3,$4,$5,$6,$7,$8)',data,(q_err:any,q_res:any)=>{
if(q_err){
console.log(q_err);
res.code = 404
@@ -38,7 +38,7 @@ export const createUser = (req:any,res:any)=>{
export const updateUser = (req:any,res:any)=>{
const {id} = req.params
const data = [req.body.firstName,req.body.middleName,req.body.lastName,req.body.email,req.body.phoneNumber,req.body.role,req.body.address,req.body.createdDate];
- pool.query('UPDATE users SET first_name=$1,middle_name=$2, last_name=$3, email=$4, phone_number=$5, role=$6, address=$7, created_date=$8 WHERE user_id=$9',[...data,id],(q_err:any,q_res:any)=>{
+ pool.query('UPDATE users SET firstName=$1,middleName=$2, lastName=$3, email=$4, phoneNumber=$5, role=$6, address=$7, createdDate=$8 WHERE userId=$9',[...data,id],(q_err:any,q_res:any)=>{
if(q_err){
console.log(q_err);
res.code = 404
diff --git a/server/src/index.ts b/server/src/index.ts
index 1804466..913337c 100644
--- a/server/src/index.ts
+++ b/server/src/index.ts
@@ -6,6 +6,6 @@ const app = express();
app.use(express.json({limit: "30mb"}));
app.use(cors());
-app.use('/user',router);
+app.use('/users',router);
app.listen(9010);
\ No newline at end of file
diff --git a/server/src/models/schema.sql b/server/src/models/schema.sql
index f6294ba..d0c7134 100644
--- a/server/src/models/schema.sql
+++ b/server/src/models/schema.sql
@@ -2,14 +2,14 @@
CREATE TYPE roleType AS ENUM ('SuperAdmin', 'Admin', 'Subscriber') DEFAULT 'Subscriber';
CREATE TABLE users(
- user_id uuid DEFAULT uuid_generate_v4 () PRIMARY KEY,
- first_name VARCHAR(255) NOT NULL,
- middle_name VARCHAR(255),
- last_name VARCHAR(255) NOT NULL,
+ userId uuid DEFAULT uuid_generate_v4 () PRIMARY KEY,
+ firstName VARCHAR(255) NOT NULL,
+ middleName VARCHAR(255),
+ lastName VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
- phone_number BIGINT NOT NULL,
+ phoneNumber BIGINT NOT NULL,
role roleType,
address VARCHAR(255) NOT NULL,
- created_date VARCHAR(255)
+ createdDate VARCHAR(255)
);