Skip to content

Commit 0d489df

Browse files
committed
Created many things
1 parent d36b4eb commit 0d489df

10 files changed

+129
-63
lines changed

angular.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@
5656
"vendorChunk": true,
5757
"extractLicenses": false,
5858
"sourceMap": true,
59-
"namedChunks": true
59+
"namedChunks": true,
60+
"fileReplacements": [
61+
{
62+
"replace": "src/environments/environment.ts",
63+
"with": "src/environments/environment.development.ts"
64+
}
65+
]
6066
}
6167
},
6268
"defaultConfiguration": "production"

src/app/features/features.module.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { NgModule } from '@angular/core';
22
import { CommonModule } from '@angular/common';
33
import { UploadPageComponent } from './pages/upload-page/upload-page.component';
44
import { ContentListPageComponent } from './pages/content-list-page/content-list-page.component';
5+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
6+
import { HttpClientModule } from '@angular/common/http'
57

68

79

@@ -11,7 +13,10 @@ import { ContentListPageComponent } from './pages/content-list-page/content-list
1113
ContentListPageComponent
1214
],
1315
imports: [
14-
CommonModule
16+
CommonModule,
17+
FormsModule,
18+
ReactiveFormsModule,
19+
HttpClientModule
1520
]
1621
})
1722
export class FeaturesModule { }

src/app/features/pages/content-list-page/content-list-page.component.html

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,18 @@
44
<h2 class="mb-4 text-4xl tracking-tight font-extrabold text-gray-900 dark:text-white">Users</h2>
55
</div>
66
<div class="grid gap-8 mb-6 lg:mb-16 md:grid-cols-2">
7-
<div class="items-center bg-gray-50 rounded-lg shadow sm:flex dark:bg-gray-800 dark:border-gray-700">
8-
<a href="#">
7+
<div class="items-center bg-gray-50 rounded-lg shadow sm:flex dark:bg-gray-800 dark:border-gray-700" *ngFor="let user of users">
8+
<a>
99
<img class="w-full rounded-lg sm:rounded-none sm:rounded-l-lg"
10-
src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/avatars/bonnie-green.png"
10+
[src]="localhost + user.profileImage"
1111
alt="Bonnie Avatar">
1212
</a>
1313
<div class="p-5">
1414
<h3 class="text-xl font-bold tracking-tight text-gray-900 dark:text-white">
15-
<a href="#">Bonnie Green</a>
15+
<a>{{user.name}}</a>
1616
</h3>
17-
<span class="text-gray-500 dark:text-gray-400">CEO & Web Developer</span>
18-
<p class="mt-3 mb-4 font-light text-gray-500 dark:text-gray-400">Bonnie drives the technical
19-
strategy of the flowbite platform and brand.</p>
20-
</div>
21-
</div>
22-
<div class="items-center bg-gray-50 rounded-lg shadow sm:flex dark:bg-gray-800 dark:border-gray-700">
23-
<a href="#">
24-
<img class="w-full rounded-lg sm:rounded-none sm:rounded-l-lg"
25-
src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/avatars/jese-leos.png"
26-
alt="Jese Avatar">
27-
</a>
28-
<div class="p-5">
29-
<h3 class="text-xl font-bold tracking-tight text-gray-900 dark:text-white">
30-
<a href="#">Jese Leos</a>
31-
</h3>
32-
<span class="text-gray-500 dark:text-gray-400">CTO</span>
33-
<p class="mt-3 mb-4 font-light text-gray-500 dark:text-gray-400">Jese drives the technical strategy
34-
of the flowbite platform and brand.</p>
35-
</div>
36-
</div>
37-
<div class="items-center bg-gray-50 rounded-lg shadow sm:flex dark:bg-gray-800 dark:border-gray-700">
38-
<a href="#">
39-
<img class="w-full rounded-lg sm:rounded-none sm:rounded-l-lg"
40-
src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/avatars/michael-gouch.png"
41-
alt="Michael Avatar">
42-
</a>
43-
<div class="p-5">
44-
<h3 class="text-xl font-bold tracking-tight text-gray-900 dark:text-white">
45-
<a href="#">Michael Gough</a>
46-
</h3>
47-
<span class="text-gray-500 dark:text-gray-400">Senior Front-end Developer</span>
48-
<p class="mt-3 mb-4 font-light text-gray-500 dark:text-gray-400">Michael drives the technical
49-
strategy of the flowbite platform and brand.</p>
50-
</div>
51-
</div>
52-
<div class="items-center bg-gray-50 rounded-lg shadow sm:flex dark:bg-gray-800 dark:border-gray-700">
53-
<a href="#">
54-
<img class="w-full rounded-lg sm:rounded-none sm:rounded-l-lg"
55-
src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/avatars/sofia-mcguire.png"
56-
alt="Sofia Avatar">
57-
</a>
58-
<div class="p-5">
59-
<h3 class="text-xl font-bold tracking-tight text-gray-900 dark:text-white">
60-
<a href="#">Lana Byrd</a>
61-
</h3>
62-
<span class="text-gray-500 dark:text-gray-400">Marketing & Sale</span>
63-
<p class="mt-3 mb-4 font-light text-gray-500 dark:text-gray-400">Lana drives the technical strategy
64-
of the flowbite platform and brand.</p>
17+
<span class="text-gray-500 dark:text-gray-400">{{user.profession}}</span>
18+
<p class="mt-3 mb-4 font-light text-gray-500 dark:text-gray-400">{{user.bio}}</p>
6519
</div>
6620
</div>
6721
</div>

src/app/features/pages/content-list-page/content-list-page.component.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
import { Component, OnInit } from '@angular/core';
22
import { Router } from '@angular/router';
33
import { initFlowbite } from 'flowbite';
4+
import { UploadService } from '../../services/upload.service';
45

56
@Component({
67
selector: 'app-content-list-page',
78
templateUrl: './content-list-page.component.html',
89
styleUrls: ['./content-list-page.component.scss']
910
})
1011
export class ContentListPageComponent implements OnInit{
11-
12-
constructor(private router:Router){}
12+
users!: any[];
13+
localhost = 'http://localhost:9090/'
14+
constructor(private router:Router, private userService:UploadService){}
1315

1416

1517
ngOnInit(): void {
1618
initFlowbite()
19+
this.getAllUsers()
20+
}
21+
22+
getAllUsers(){
23+
this.userService.getAllUsers().subscribe((data)=>{
24+
this.users = data;
25+
console.log(this.users);
26+
});
1727
}
1828

1929
addUser(){

src/app/features/pages/upload-page/upload-page.component.html

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<section class="bg-white dark:bg-gray-900">
22
<div class="py-8 px-4 mx-auto max-w-2xl lg:py-16">
33
<h2 class="mb-4 text-xl font-bold text-gray-900 dark:text-white">Add a new user</h2>
4-
<form action="#">
4+
<form [formGroup]="userForm">
55
<div class="grid gap-4 sm:grid-cols-2 sm:gap-6">
66
<div class="sm:col-span-2">
77
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Profile image</label>
@@ -20,36 +20,52 @@ <h2 class="mb-4 text-xl font-bold text-gray-900 dark:text-white">Add a new user<
2020
or drag and drop</p>
2121
<p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF (MAX. 800x400px)</p>
2222
</div>
23-
<input id="dropzone-file" type="file" class="hidden" />
23+
<input id="dropzone-file" (change)="handleImageInput($event)" type="file" class="hidden" />
2424
</label>
25+
2526
</div>
27+
<small class="text-danger" *ngIf="!imageToUpload">Add your profile image !</small>
28+
</div>
29+
<div class="sm:col-span-2">
30+
<img width="100%" *ngIf="imageUrl" [src]="imageUrl" class="image">
2631
</div>
2732
<div class="sm:col-span-2">
2833
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Email</label>
2934
<input type="email" name="email" id="email"
35+
formControlName="email"
3036
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
3137
placeholder="Email" required="">
38+
<small class="text-danger" *ngIf="emailControl?.touched && emailControl?.hasError('required')">This field is required !</small>
39+
<small class="text-danger" *ngIf="emailControl?.touched && emailControl?.hasError('pattern')">This field is required !</small>
3240
</div>
3341
<div class="w-full">
3442
<label for="name"
3543
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Name</label>
3644
<input type="text" name="name" id="name"
45+
formControlName="name"
3746
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
3847
placeholder="Name" required="">
48+
<small class="text-danger" *ngIf="nameControl?.touched && nameControl?.hasError('required')">This field is required !</small>
49+
3950
</div>
4051
<div class="w-full">
4152
<label for="price"
4253
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Profession</label>
4354
<input type="text" name="profession" id="profession"
55+
formControlName="profession"
4456
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
4557
placeholder="Profession" required="">
58+
<small class="text-danger" *ngIf="professionControl?.touched && professionControl?.hasError('required')">This field is required !</small>
59+
4660
</div>
4761
<div class="sm:col-span-2">
4862
<label for="bio"
4963
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Bio</label>
5064
<textarea id="bio" rows="8"
65+
formControlName="bio"
5166
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
5267
placeholder="Your bio here"></textarea>
68+
<small class="text-danger" *ngIf="bioControl?.touched && bioControl?.hasError('required')">This field is required !</small>
5369
</div>
5470
</div>
5571
</form>

src/app/features/pages/upload-page/upload-page.component.ts

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,74 @@
11
import { Component, OnInit } from '@angular/core';
2+
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
23
import { Router } from '@angular/router';
34
import { initFlowbite } from 'flowbite';
5+
import { UploadService } from '../../services/upload.service';
46

57
@Component({
68
selector: 'app-upload-page',
79
templateUrl: './upload-page.component.html',
810
styleUrls: ['./upload-page.component.scss']
911
})
1012
export class UploadPageComponent implements OnInit{
13+
imageToUpload!: any;
14+
imageUrl: any;
15+
userForm!: FormGroup;
1116

12-
constructor(private router: Router) { }
17+
constructor(private router: Router, private formBuilder:FormBuilder, private userService:UploadService) { }
1318

1419

1520
ngOnInit(): void {
16-
initFlowbite()
21+
initFlowbite();
22+
this.initializeUserForm();
23+
}
24+
25+
initializeUserForm(){
26+
this.userForm = this.formBuilder.group({
27+
email: [null, [Validators.required, Validators.pattern('')]],
28+
name: [null, Validators.required],
29+
profession: [null, Validators.required],
30+
bio: [null, Validators.required],
31+
profileImage: [null]
32+
})
33+
}
34+
35+
get emailControl(){
36+
return this.userForm.get('email')
37+
}
38+
39+
get nameControl() {
40+
return this.userForm.get('name')
41+
}
42+
43+
get professionControl() {
44+
return this.userForm.get('profession')
45+
}
46+
47+
get bioControl() {
48+
return this.userForm.get('bio')
49+
}
50+
51+
handleImageInput(event:any){
52+
this.imageToUpload = event?.target.files.item(0);
53+
let reader = new FileReader();
54+
reader.onload = (event:any)=>{
55+
this.imageUrl = event.target.result;
56+
}
57+
reader.readAsDataURL(this.imageToUpload);
1758
}
1859

1960
addUser() {
20-
this.navigateToUserList();
61+
const formData = new FormData();
62+
formData.append('user', JSON.stringify(this.userForm.value));
63+
formData.append('image', this.imageToUpload);
64+
this.userService.saveUser(formData).subscribe((data)=>{
65+
console.log("SAVED")
66+
this.navigateToUserList();
67+
},
68+
(error)=>{
69+
console.error(error);
70+
}
71+
)
2172
}
2273

2374
navigateToUserList(){
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
import { Injectable } from '@angular/core';
2+
import { HttpClient } from '@angular/common/http'
3+
import { Observable } from 'rxjs';
4+
import { environment } from 'src/environments/environment';
5+
26

37
@Injectable({
48
providedIn: 'root'
59
})
610
export class UploadService {
711

8-
constructor() { }
12+
apiUrl = environment.apiUrl + 'users'
13+
14+
constructor(private httpClient:HttpClient) { }
15+
16+
saveUser(data:any):Observable<any>{
17+
return this.httpClient.post(this.apiUrl, data);
18+
}
19+
20+
getAllUsers(): Observable<any> {
21+
return this.httpClient.get(this.apiUrl);
22+
}
923
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const environment = {
2+
apiUrl: 'http://localhost:9090/api/'
3+
};

src/environments/environment.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const environment = {
2+
apiUrl: 'http://localhost:9090/api/'
3+
};

src/styles.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
/* You can add global styles to this file, and also import other style files */
22
@tailwind base;
33
@tailwind components;
4-
@tailwind utilities;
4+
@tailwind utilities;
5+
6+
.text-danger{
7+
color: red;
8+
}

0 commit comments

Comments
 (0)