Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
Meu-Template-Angular-CSR
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Trần Anh Phú
Meu-Template-Angular-CSR
Commits
945c4ad3
Commit
945c4ad3
authored
Dec 04, 2024
by
tinhbe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update done JobManagement Admin
parent
1d05da0f
Changes
34
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
590 additions
and
361 deletions
+590
-361
Job.component.html
src/app/+admin/Management/Job/Job.component.html
+102
-0
Job.component.scss
src/app/+admin/Management/Job/Job.component.scss
+0
-0
Job.component.ts
src/app/+admin/Management/Job/Job.component.ts
+209
-0
Management.routes.ts
src/app/+admin/Management/Job/Management.routes.ts
+15
-0
jobForm.component.html
...min/Management/job/feature/jobForm/jobForm.component.html
+0
-109
jobForm.component.ts
...admin/Management/job/feature/jobForm/jobForm.component.ts
+0
-53
jobLayout.component.html
...Management/job/feature/jobLayout/jobLayout.component.html
+0
-2
jobLayout.component.ts
...n/Management/job/feature/jobLayout/jobLayout.component.ts
+0
-20
jobList.component.html
...min/Management/job/feature/jobList/jobList.component.html
+0
-35
jobList.component.ts
...admin/Management/job/feature/jobList/jobList.component.ts
+0
-67
admin.routes.ts
src/app/+admin/admin.routes.ts
+1
-1
jobModel.model.ts
src/app/+admin/data-access/model/jobModel.model.ts
+1
-1
JobService.service.ts
src/app/+admin/data-access/services/JobService.service.ts
+21
-5
header.component.html
...layout/feature/ui/Components/header/header.component.html
+4
-0
header.component.ts
...n/layout/feature/ui/Components/header/header.component.ts
+3
-2
layout.component.html
src/app/+admin/layout/feature/ui/layout.component.html
+8
-28
layout.component.ts
src/app/+admin/layout/feature/ui/layout.component.ts
+4
-3
JobCard.component.html
src/app/+home/component/JobCard/JobCard.component.html
+6
-0
JobCard.component.ts
src/app/+home/component/JobCard/JobCard.component.ts
+13
-0
JobListCard.component.html
...pp/+home/component/JobListCard/JobListCard.component.html
+4
-0
JobListCard.component.ts
src/app/+home/component/JobListCard/JobListCard.component.ts
+20
-0
home.component.html
src/app/+home/feature/home.component.html
+2
-1
home.component.ts
src/app/+home/feature/home.component.ts
+4
-2
footer.component.html
...me/layout/feature/Components/footer/footer.component.html
+33
-0
footer.component.ts
...home/layout/feature/Components/footer/footer.component.ts
+17
-0
header.component.html
...me/layout/feature/Components/header/header.component.html
+20
-0
header.component.ts
...home/layout/feature/Components/header/header.component.ts
+13
-0
Auth.Service.ts
src/app/+login/data-access/Services/Auth.Service.ts
+49
-0
admin.guard.ts
src/app/+login/data-access/guard/admin.guard.ts
+1
-1
auth.guard.ts
src/app/+login/data-access/guard/auth.guard.ts
+7
-3
login.guard.ts
src/app/+login/data-access/guard/login.guard.ts
+17
-0
login.component.html
src/app/+login/feature/login.component.html
+1
-13
login.component.ts
src/app/+login/feature/login.component.ts
+5
-13
shell.routes.ts
src/app/+shell/feature/shell.routes.ts
+10
-2
No files found.
src/app/+admin/Management/Job/Job.component.html
0 → 100644
View file @
945c4ad3
<div
className=
"tw-container tw-content-center"
>
<div
class=
"tw-flex tw-justify-end tw-pb-5"
>
<button
nz-button
nzType=
"primary"
(
click
)="
addJob
()"
>
+ Thêm công việc mới
</button>
</div>
<nz-table
#
JobTable
[
nzData
]="
listOfJob
"
[
nzLoading
]="
loading
"
[
nzFrontPagination
]="
true
"
nzShowSizeChanger
[
nzPageSize
]="
5
"
>
<thead>
<tr>
<th>
STT
</th>
<th>
Loại công việc
</th>
<th>
Tiêu đề
</th>
<th>
Công ty
</th>
<th>
Địa chỉ
</th>
<th>
Thao tác
</th>
</tr>
</thead>
<tbody>
@for (data of JobTable.data; track data) {
<tr>
<td>
{{ listOfJob.indexOf(data) + 1 }}
</td>
<td>
{{ data.type }}
</td>
<td>
{{ data.title }}
</td>
<td>
{{ data.company }}
</td>
<td>
{{ data.location }}
</td>
<td>
<nz-space>
<button
class=
"tw-mr-2"
nz-button
nzType=
"primary"
nzSize=
"small"
(
click
)="
JobDetail
(
data
.
id
)"
>
Xem chi tiết
</button>
<button
class=
"tw-mr-2"
nz-button
nzType=
"default"
nzSize=
"small"
(
click
)="
onEdit
(
data
)"
>
Sửa
</button>
<button
nz-button
nzType=
"dashed"
nzSize=
"small"
nzDanger
(
click
)="
showDeleteConfirm
(
data
.
id
)"
>
Xóa
</button>
</nz-space>
</td>
</tr>
}
</tbody>
</nz-table>
<nz-modal
[(
nzVisible
)]="
isOpenModal
"
[
nzTitle
]="
isOnEdit
?
'
S
ử
a
c
ô
ng
vi
ệ
c
'
:
'
Chi
ti
ế
t
c
ô
ng
vi
ệ
c
'"
(
nzOnOk
)="
onOk
()"
(
nzOnCancel
)="
onCancel
()"
>
<ng-container
*
nzModalContent
>
<div
*
ngIf=
"selectedJob"
>
<form
nz-form
[
formGroup
]="
validateJobForm
"
>
<nz-form-item>
<nz-form-label
[
nzSpan
]="
7
"
>
Loại công việc
</nz-form-label>
<nz-form-control
[
nzSpan
]="
17
"
>
<nz-select
formControlName=
"type"
placeholder=
"Loại công việc"
ngModel=
{{selectedJob.type}}
>
<nz-option
nzValue=
"Full Time"
nzLabel=
"Full Time"
></nz-option>
<nz-option
nzValue=
"Part Time"
nzLabel=
"Part Time"
></nz-option>
<nz-option
nzValue=
"Freelance"
nzLabel=
"Freelance"
></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label
[
nzSpan
]="
7
"
>
Tên công việc
</nz-form-label>
<nz-form-control
[
nzSpan
]="
17
"
>
<input
class=
"tw-w-full tw-p-2 tw-bg-white tw-border tw-rounded-md focus:tw-outline-none focus:tw-ring-1 focus:tw-ring-blue-500 focus:tw-border-blue-500"
nz-input
formControlName=
"location"
nz-input
formControlName=
"title"
placeholder=
"Tên công việc"
[
ngModel
]="
selectedJob
.
title
"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label
[
nzSpan
]="
7
"
>
Công ty
</nz-form-label>
<nz-form-control
[
nzSpan
]="
17
"
>
<input
class=
"tw-w-full tw-p-2 tw-bg-white tw-border tw-rounded-md focus:tw-outline-none focus:tw-ring-1 focus:tw-ring-blue-500 focus:tw-border-blue-500"
nz-input
formControlName=
"location"
nz-input
formControlName=
"company"
placeholder=
"Công ty"
[
ngModel
]="
selectedJob
.
company
"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label
[
nzSpan
]="
7
"
>
Địa chỉ
</nz-form-label>
<nz-form-control
[
nzSpan
]="
17
"
>
<input
class=
"tw-w-full tw-p-2 tw-bg-white tw-border tw-rounded-md focus:tw-outline-none focus:tw-ring-1 focus:tw-ring-blue-500 focus:tw-border-blue-500"
nz-input
formControlName=
"location"
placeholder=
"Địa chỉ"
[
ngModel
]="
selectedJob
.
location
"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label
[
nzSpan
]="
7
"
>
Mô tả
</nz-form-label>
<nz-form-control
[
nzSpan
]="
17
"
>
<textarea
class=
"tw-w-full tw-h-40 tw-p-2 tw-bg-white tw-border tw-rounded-md focus:tw-outline-none focus:tw-ring-1 focus:tw-ring-blue-500 focus:tw-border-blue-500"
nz-input
formControlName=
"description"
placeholder=
"Mô tả công việc"
[
ngModel
]="
selectedJob
.
description
"
></textarea>
</nz-form-control>
</nz-form-item>
</form>
</div>
</ng-container>
</nz-modal>
</div>
src/app/+admin/Management/Job/Job.component.scss
0 → 100644
View file @
945c4ad3
src/app/+admin/Management/Job/Job.component.ts
0 → 100644
View file @
945c4ad3
//#region imports
import
{
CommonModule
}
from
"@angular/common"
;
import
{
Component
,
OnInit
}
from
"@angular/core"
;
import
{
JobService
}
from
"../../data-access/services/JobService.service"
;
import
{
NzTableModule
,
NzTableQueryParams
}
from
'ng-zorro-antd/table'
;
import
{
catchError
,
finalize
,
of
,
tap
}
from
"rxjs"
;
import
{
JobModel
}
from
"../../data-access/model/jobModel.model"
;
import
{
NzDividerModule
}
from
'ng-zorro-antd/divider'
;
import
{
NzButtonModule
}
from
"ng-zorro-antd/button"
;
import
{
NzSpaceModule
}
from
'ng-zorro-antd/space'
;
import
{
NzModalModule
,
NzModalService
}
from
'ng-zorro-antd/modal'
;
import
{
FormBuilder
,
ReactiveFormsModule
,
Validators
}
from
"@angular/forms"
;
import
{
NzFormModule
}
from
"ng-zorro-antd/form"
;
import
{
NzSelectModule
}
from
'ng-zorro-antd/select'
;
//#endregion
//#region Component
@
Component
({
selector
:
"meu-admin-job"
,
templateUrl
:
"./Job.component.html"
,
standalone
:
true
,
imports
:
[
CommonModule
,
NzTableModule
,
NzDividerModule
,
NzButtonModule
,
NzSpaceModule
,
NzModalModule
,
NzModalModule
,
NzFormModule
,
ReactiveFormsModule
,
NzSelectModule
],
})
//#endregion
export
class
JobComponent
implements
OnInit
{
//#region Variable
selectedJob
?:
JobModel
;
listOfJob
:
JobModel
[]
=
[];
loading
=
true
;
message
=
""
;
//modal
isOpenModal
=
false
;
isOnEdit
=
false
;
isOnAdd
=
false
;
validateJobForm
=
this
.
fb
.
group
({
type
:
this
.
fb
.
control
(
''
,
[
Validators
.
required
]),
create_at
:
this
.
fb
.
control
(
''
,
[
Validators
.
required
]),
company_url
:
this
.
fb
.
control
(
''
,
[
Validators
.
required
]),
company
:
this
.
fb
.
control
(
''
,
[
Validators
.
required
]),
location
:
this
.
fb
.
control
(
''
,
[
Validators
.
required
]),
title
:
this
.
fb
.
control
(
''
,
[
Validators
.
required
]),
description
:
this
.
fb
.
control
(
''
,
[
Validators
.
required
]),
});
//#endregion
//#region LoadData
constructor
(
private
fb
:
FormBuilder
,
private
jobService
:
JobService
,
private
modal
:
NzModalService
)
{}
loadDataFromServer
():
void
{
this
.
loading
=
true
;
this
.
jobService
.
jobsGet
().
pipe
(
tap
((
res
)
=>
{
this
.
listOfJob
=
res
.
responseData
.
items
;
}),
catchError
((
err
)
=>
{
console
.
log
(
err
);
return
of
(
null
);
}),
finalize
(()
=>
(
this
.
loading
=
false
))
).
subscribe
();
}
ngOnInit
():
void
{
this
.
loadDataFromServer
();
}
//#endregion
//#region Handler
resetForm
()
{
this
.
validateJobForm
.
reset
();
this
.
selectedJob
=
{}
as
JobModel
;
}
EnableForm
()
{
this
.
validateJobForm
.
enable
();
}
DisableForm
()
{
this
.
validateJobForm
.
disable
();
}
onOk
():
void
{
console
.
log
(
this
.
onEdit
,
this
.
selectedJob
);
if
(
this
.
isOnEdit
&&
this
.
selectedJob
)
{
const
updatedJob
:
JobModel
=
{
id
:
this
.
selectedJob
.
id
,
type
:
this
.
validateJobForm
.
value
.
type
??
undefined
,
created_at
:
this
.
selectedJob
.
created_at
,
company
:
this
.
validateJobForm
.
value
.
company
??
undefined
,
company_url
:
this
.
validateJobForm
.
value
.
company_url
??
undefined
,
location
:
this
.
validateJobForm
.
value
.
location
??
undefined
,
title
:
this
.
validateJobForm
.
value
.
title
??
undefined
,
description
:
this
.
validateJobForm
.
value
.
description
??
undefined
,
};
this
.
loading
=
true
;
this
.
jobService
.
editJob
(
updatedJob
).
pipe
(
tap
((
res
)
=>
{
this
.
message
=
res
.
message
;
this
.
loadDataFromServer
();
}),
catchError
((
err
)
=>
{
console
.
error
(
err
);
return
of
(
null
);
})
).
subscribe
();
}
else
if
(
this
.
isOnAdd
&&
this
.
selectedJob
)
{
const
newJob
:
JobModel
=
{
id
:
this
.
selectedJob
.
id
,
type
:
this
.
validateJobForm
.
value
.
type
??
undefined
,
created_at
:
this
.
selectedJob
.
created_at
,
company
:
this
.
validateJobForm
.
value
.
company
??
undefined
,
company_url
:
this
.
validateJobForm
.
value
.
company_url
??
undefined
,
location
:
this
.
validateJobForm
.
value
.
location
??
undefined
,
title
:
this
.
validateJobForm
.
value
.
title
??
undefined
,
description
:
this
.
validateJobForm
.
value
.
description
??
undefined
,
};
this
.
loading
=
true
;
this
.
jobService
.
addingNewJob
(
newJob
).
pipe
(
tap
((
res
)
=>
{
this
.
message
=
res
.
message
;
this
.
loadDataFromServer
();
}),
catchError
((
err
)
=>
{
console
.
error
(
err
);
return
of
(
null
);
})
).
subscribe
();
}
this
.
isOpenModal
=
false
;
this
.
isOnEdit
=
false
;
this
.
isOnAdd
=
false
;
}
onCancel
():
void
{
this
.
isOpenModal
=
false
;
this
.
isOnEdit
=
false
;
}
//#endregion
//#region Action
JobDetail
(
id
:
string
)
{
this
.
DisableForm
();
this
.
isOnEdit
=
false
;
this
.
isOpenModal
=
true
;
this
.
isOnAdd
=
false
;
this
.
jobService
.
getJob
(
id
).
pipe
(
tap
((
res
)
=>
{
this
.
selectedJob
=
res
.
responseData
;
}),
catchError
((
err
)
=>
{
console
.
log
(
err
);
return
of
(
null
);
}),
finalize
(()
=>
this
.
loading
=
false
)
).
subscribe
();
}
onDelete
(
id
:
string
)
{
this
.
jobService
.
deleteJob
(
id
).
pipe
(
tap
((
res
)
=>
{
this
.
loading
=
true
;
this
.
message
=
res
.
message
;
}),
catchError
((
err
)
=>
{
console
.
log
(
err
);
return
of
(
null
);
}),
finalize
(()
=>
(
this
.
loadDataFromServer
(),
this
.
loading
=
false
))
).
subscribe
();
}
onEdit
(
data
:
JobModel
)
{
this
.
EnableForm
();
this
.
isOpenModal
=
true
;
this
.
isOnEdit
=
true
;
this
.
isOnAdd
=
false
;
this
.
selectedJob
=
data
;
}
addJob
(){
this
.
EnableForm
();
this
.
resetForm
();
this
.
isOpenModal
=
true
;
this
.
isOnEdit
=
false
;
this
.
isOnAdd
=
true
;
}
showDeleteConfirm
(
id
:
string
):
void
{
this
.
modal
.
confirm
({
nzTitle
:
'Bạn có chắc rằng xóa công việc này không?'
,
nzOkText
:
'Xóa'
,
nzOkType
:
'primary'
,
nzOkDanger
:
true
,
nzOnOk
:
()
=>
this
.
onDelete
(
id
),
nzCancelText
:
'trở về'
,
});
}
//#endregion
}
src/app/+admin/Management/
job/job
.routes.ts
→
src/app/+admin/Management/
Job/Management
.routes.ts
View file @
945c4ad3
...
...
@@ -3,17 +3,10 @@ import { Route } from '@angular/router';
// file: job.routes.ts
const
JOB_ROUTES
:
Route
[]
=
[
{
path
:
'
jobLayout
'
,
path
:
'
Job
'
,
loadComponent
:
()
=>
import
(
'./feature/jobLayout/jobLayout.component'
).
then
(
(
m
)
=>
m
.
JobLayoutComponent
),
},
{
path
:
'jobForm'
,
loadComponent
:
()
=>
import
(
'./feature/jobForm/jobForm.component'
).
then
(
(
m
)
=>
m
.
JobFormComponent
import
(
'../Job/Job.component'
).
then
(
(
m
)
=>
m
.
JobComponent
),
},
];
...
...
src/app/+admin/Management/job/feature/jobForm/jobForm.component.html
deleted
100644 → 0
View file @
1d05da0f
<nz-card
nzTitle=
"Thêm công việc mới"
[
nzBordered
]="
true
"
style=
"width: 600px; margin: 0 auto; margin-top: 50px;"
>
<form
nz-form
(
ngSubmit
)="
onSubmit
()"
#
jobForm=
"ngForm"
>
<!-- Tiêu đề công việc -->
<nz-form-item>
<nz-form-label
nzFor=
"title"
[
nzSpan
]="
6
"
>
Tiêu đề
</nz-form-label>
<nz-form-control
[
nzSpan
]="
18
"
>
<input
nz-input
type=
"text"
id=
"title"
name=
"title"
[(
ngModel
)]="
job
.
title
"
required
placeholder=
"Nhập tiêu đề công việc"
/>
</nz-form-control>
</nz-form-item>
<!-- Loại công việc -->
<nz-form-item>
<nz-form-label
nzFor=
"type"
[
nzSpan
]="
6
"
>
Loại
</nz-form-label>
<nz-form-control
[
nzSpan
]="
18
"
>
<nz-select
id=
"type"
name=
"type"
[(
ngModel
)]="
job
.
type
"
required
placeholder=
"Chọn loại công việc"
>
<nz-option
nzValue=
"Full-time"
nzLabel=
"Full-time"
></nz-option>
<nz-option
nzValue=
"Part-time"
nzLabel=
"Part-time"
></nz-option>
<nz-option
nzValue=
"Freelance"
nzLabel=
"Freelance"
></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<!-- Công ty -->
<nz-form-item>
<nz-form-label
nzFor=
"company"
[
nzSpan
]="
6
"
>
Công ty
</nz-form-label>
<nz-form-control
[
nzSpan
]="
18
"
>
<input
nz-input
type=
"text"
id=
"company"
name=
"company"
[(
ngModel
)]="
job
.
company
"
required
placeholder=
"Nhập tên công ty"
/>
</nz-form-control>
</nz-form-item>
<!-- URL công ty -->
<nz-form-item>
<nz-form-label
nzFor=
"company_url"
[
nzSpan
]="
6
"
>
Website
</nz-form-label>
<nz-form-control
[
nzSpan
]="
18
"
>
<input
nz-input
type=
"url"
id=
"company_url"
name=
"company_url"
[(
ngModel
)]="
job
.
company_url
"
placeholder=
"Nhập URL của công ty"
/>
</nz-form-control>
</nz-form-item>
<!-- Địa điểm -->
<nz-form-item>
<nz-form-label
nzFor=
"location"
[
nzSpan
]="
6
"
>
Địa điểm
</nz-form-label>
<nz-form-control
[
nzSpan
]="
18
"
>
<input
nz-input
type=
"text"
id=
"location"
name=
"location"
[(
ngModel
)]="
job
.
location
"
required
placeholder=
"Nhập địa điểm công việc"
/>
</nz-form-control>
</nz-form-item>
<!-- Mô tả -->
<nz-form-item>
<nz-form-label
nzFor=
"description"
[
nzSpan
]="
6
"
>
Mô tả
</nz-form-label>
<nz-form-control
[
nzSpan
]="
18
"
>
<textarea
nz-input
id=
"description"
name=
"description"
[(
ngModel
)]="
job
.
description
"
rows=
"4"
placeholder=
"Nhập mô tả công việc"
required
></textarea>
</nz-form-control>
</nz-form-item>
<!-- Nút Gửi -->
<nz-form-item>
<nz-form-control
[
nzSpan
]="
18
"
[
nzOffset
]="
6
"
>
<button
nz-button
nzType=
"primary"
[
disabled
]="!
jobForm
.
valid
"
>
Thêm Công Việc
</button>
</nz-form-control>
</nz-form-item>
</form>
</nz-card>
src/app/+admin/Management/job/feature/jobForm/jobForm.component.ts
deleted
100644 → 0
View file @
1d05da0f
import
{
CommonModule
}
from
"@angular/common"
;
import
{
Component
}
from
"@angular/core"
;
import
{
NzBreadCrumbModule
}
from
"ng-zorro-antd/breadcrumb"
;
import
{
NzButtonModule
}
from
"ng-zorro-antd/button"
;
import
{
NzCardModule
}
from
"ng-zorro-antd/card"
;
import
{
NzFormModule
}
from
"ng-zorro-antd/form"
;
import
{
NzIconModule
}
from
"ng-zorro-antd/icon"
;
import
{
NzLayoutModule
}
from
"ng-zorro-antd/layout"
;
import
{
NzMenuModule
}
from
"ng-zorro-antd/menu"
;
import
{
NzToolTipModule
}
from
"ng-zorro-antd/tooltip"
;
import
{
NzSelectModule
}
from
'ng-zorro-antd/select'
;
import
{
FormsModule
}
from
"@angular/forms"
;
import
{
JobModel
}
from
"../../data-access/model/jobModel.model"
;
import
{
JobService
}
from
"../../data-access/services/JobService.service"
;
import
{
NzNotificationService
}
from
'ng-zorro-antd/notification'
;
import
{
finalize
}
from
"rxjs"
;
@
Component
({
selector
:
"app-job-form"
,
templateUrl
:
"./jobForm.component.html"
,
standalone
:
true
,
imports
:
[
CommonModule
,
NzButtonModule
,
NzBreadCrumbModule
,
NzIconModule
,
NzLayoutModule
,
NzMenuModule
,
NzToolTipModule
,
NzCardModule
,
NzFormModule
,
NzSelectModule
,
FormsModule
],
})
export
class
JobFormComponent
{
job
:
JobModel
=
{
type
:
''
,
created_at
:
new
Date
().
toISOString
(),
company
:
''
,
company_url
:
''
,
location
:
''
,
title
:
''
,
description
:
''
};
constructor
(
private
jobService
:
JobService
,
private
notification
:
NzNotificationService
)
{}
onSubmit
()
{
console
.
log
(
'Job Data:'
,
this
.
job
);
this
.
jobService
.
addingNewJob
(
this
.
job
).
pipe
(
finalize
(()
=>
this
.
notification
.
success
(
'Success'
,
'Thêm thành công'
))
).
subscribe
();
}
}
src/app/+admin/Management/job/feature/jobLayout/jobLayout.component.html
deleted
100644 → 0
View file @
1d05da0f
<span
class=
"tw-text-3xl tw-font-bold"
>
Danh sách công việc
</span>
<app-job-list></app-job-list>
src/app/+admin/Management/job/feature/jobLayout/jobLayout.component.ts
deleted
100644 → 0
View file @
1d05da0f
import
{
CommonModule
}
from
"@angular/common"
;
import
{
Component
}
from
"@angular/core"
;
import
{
RouterModule
,
RouterOutlet
}
from
"@angular/router"
;
import
{
JobListComponent
}
from
"../jobList/jobList.component"
;
import
{
JobFormComponent
}
from
"../jobForm/jobForm.component"
;
@
Component
({
selector
:
"app-jobLayout"
,
templateUrl
:
"./jobLayout.component.html"
,
standalone
:
true
,
imports
:
[
CommonModule
,
RouterModule
,
JobListComponent
,
],
})
export
class
JobLayoutComponent
{
constructor
()
{}
}
src/app/+admin/Management/job/feature/jobList/jobList.component.html
deleted
100644 → 0
View file @
1d05da0f
<nz-table
#
JobTable
[
nzData
]="
listOfJob
"
[
nzLoading
]="
loading
"
[
nzFrontPagination
]="
true
"
nzShowSizeChanger
[
nzPageSize
]="
5
"
>
<thead>
<tr>
<th>
STT
</th>
<th>
Loại công việc
</th>
<th>
Tên công việc
</th>
<th>
Công ty
</th>
<th>
Địa chỉ
</th>
<th>
Thao tác
</th>
</tr>
</thead>
<tbody>
@for (data of JobTable.data; track data) {
<tr>
<td>
{{ listOfJob.indexOf(data) + 1 }}
</td>
<td>
{{ data.type }}
</td>
<td>
{{ data.title }}
</td>
<td>
{{ data.company }}
</td>
<td>
{{ data.location }}
</td>
<td>
<nz-space
nzSize=
"small"
>
<button
nz-button
class=
"tw-mr-2"
nzType=
"default"
nzSize=
"small"
>
Xem chi tiết
</button>
<button
class=
"tw-mr-2"
nz-button
nzType=
"primary"
nzSize=
"small"
(
click
)="
onEdit
(
data
)"
>
Sửa
</button>
<button
nz-button
nzType=
"primary"
nzSize=
"small"
nzDanger
(
click
)="
onDelete
(
data
)"
>
Xóa
</button>
</nz-space>
</td>
</tr>
}
</tbody>
</nz-table>
src/app/+admin/Management/job/feature/jobList/jobList.component.ts
deleted
100644 → 0
View file @
1d05da0f
import
{
CommonModule
}
from
"@angular/common"
;
import
{
Component
,
OnInit
}
from
"@angular/core"
;
import
{
JobService
}
from
"../../data-access/services/JobService.service"
;
import
{
NzTableModule
,
NzTableQueryParams
}
from
'ng-zorro-antd/table'
;
import
{
catchError
,
finalize
,
of
,
tap
}
from
"rxjs"
;
import
{
JobModel
}
from
"../../data-access/model/jobModel.model"
;
import
{
NzDividerModule
}
from
'ng-zorro-antd/divider'
;
import
{
NzButtonModule
}
from
"ng-zorro-antd/button"
;
import
{
NzSpaceModule
}
from
'ng-zorro-antd/space'
;
import
{
NzNotificationService
}
from
'ng-zorro-antd/notification'
;
@
Component
({
selector
:
"app-job-list"
,
templateUrl
:
"./jobList.component.html"
,
standalone
:
true
,
imports
:
[
CommonModule
,
NzTableModule
,
NzDividerModule
,
NzButtonModule
,
NzSpaceModule
],
})
export
class
JobListComponent
implements
OnInit
{
total
=
1
;
listOfJob
:
JobModel
[]
=
[];
loading
=
true
;
pageSize
=
15
;
pageIndex
=
1
;
loadDataFromServer
(
pageIndex
:
number
,
pageSize
:
number
):
void
{
this
.
loading
=
true
;
this
.
jobService
.
jobsGet
(
pageIndex
,
pageSize
).
pipe
(
tap
((
res
)
=>
{
this
.
loading
=
false
;
this
.
total
=
res
.
total
;
this
.
listOfJob
=
res
.
responseData
.
items
;
console
.
log
(
this
.
listOfJob
);
}),
catchError
((
err
)
=>
{
console
.
log
(
err
);
return
of
(
null
);
})
).
subscribe
();
}
constructor
(
private
jobService
:
JobService
,
private
notification
:
NzNotificationService
)
{}
ngOnInit
():
void
{
this
.
loadDataFromServer
(
this
.
pageIndex
,
this
.
pageSize
);
}
onEdit
(
data
:
any
)
{
console
.
log
(
data
);
}
onDelete
(
data
:
any
)
{
this
.
jobService
.
deleteJob
(
data
.
id
).
pipe
(
finalize
(()
=>
{
this
.
notification
.
success
(
'Success'
,
'Xóa thành công'
);
this
.
listOfJob
=
this
.
listOfJob
.
filter
(
job
=>
job
.
id
!==
data
.
id
);
})
).
subscribe
();
}
}
src/app/+admin/admin.routes.ts
View file @
945c4ad3
...
...
@@ -11,7 +11,7 @@ const ADMIN_ROUTES: Route[] = [
children
:
[
{
path
:
''
,
loadChildren
:
()
=>
import
(
'./Management/
job/job
.routes'
),
loadChildren
:
()
=>
import
(
'./Management/
Job/Management
.routes'
),
},
]
}
...
...
src/app/+admin/
Management/job/
data-access/model/jobModel.model.ts
→
src/app/+admin/data-access/model/jobModel.model.ts
View file @
945c4ad3
export
interface
JobModel
{
id
?
:
string
;
id
:
string
;
type
?:
string
;
created_at
:
string
;
company
?:
string
;
...
...
src/app/+admin/
Management/job/
data-access/services/JobService.service.ts
→
src/app/+admin/data-access/services/JobService.service.ts
View file @
945c4ad3
import
{
Injectable
}
from
'@angular/core'
;
import
{
HttpClient
,
HttpHeaders
,
HttpParams
,
HttpRequest
}
from
'@angular/common/http'
;
import
{
Observable
}
from
'rxjs'
;
import
{
environment
}
from
'../../../../../../environments/environment.development'
;
import
{
environment
}
from
'../../../../environments/environment.development'
;
import
{
JobModel
}
from
'../model/jobModel.model'
;
@
Injectable
({
providedIn
:
'root'
,
})
export
class
JobService
{
apiUrl
=
environment
.
API_DOMAIN
+
'/jobs'
;
apiUrlById
=
environment
.
API_DOMAIN
+
'/jobById'
;
constructor
(
private
http
:
HttpClient
)
{}
jobsGet
(
pageNumber
:
number
,
pageSize
:
number
):
Observable
<
any
>
{
jobsGet
():
Observable
<
any
>
{
const
params
=
new
HttpParams
()
.
set
(
'pageNumber'
,
pageNumber
.
toString
())
.
set
(
'pageSize'
,
pageSize
.
toString
());
return
this
.
http
.
get
<
any
>
(
this
.
apiUrl
,
{
params
});
}
addingNewJob
(
data
:
any
):
Observable
<
any
>
{
addingNewJob
(
data
:
JobModel
):
Observable
<
any
>
{
const
headers
=
new
HttpHeaders
()
.
set
(
'Content-Type'
,
'application/json'
)
.
set
(
'authorization'
,
`Bearer
${
localStorage
.
getItem
(
'token'
)}
`
);
...
...
@@ -29,5 +30,20 @@ export class JobService {
const
url
=
`
${
this
.
apiUrl
}
/
${
id
}
`
;
return
this
.
http
.
delete
<
any
>
(
url
,
{
headers
});
}
editJob
(
data
:
JobModel
):
Observable
<
any
>
{
const
headers
=
new
HttpHeaders
()
.
set
(
'Content-Type'
,
'application/json'
)
.
set
(
'Authorization'
,
`Bearer
${
localStorage
.
getItem
(
'token'
)}
`
);
const
url
=
`
${
this
.
apiUrl
}
/
${
data
.
id
}
`
;
return
this
.
http
.
put
<
any
>
(
url
,
data
,
{
headers
});
}
getJob
(
id
:
string
):
Observable
<
any
>
{
const
headers
=
new
HttpHeaders
()
.
set
(
'Content-Type'
,
'application/json'
)
.
set
(
'Authorization'
,
`Bearer
${
localStorage
.
getItem
(
'token'
)}
`
);
const
url
=
`
${
this
.
apiUrlById
}
/
${
id
}
`
;
console
.
log
(
id
,
url
);
return
this
.
http
.
get
<
any
>
(
url
,
{
headers
});
}
}
src/app/+admin/layout/feature/ui/Components/header/header.component.html
View file @
945c4ad3
<header
class=
"tw-flex tw-justify-between tw-items-center tw-p-4 tw-bg-gray-900"
>
<h3
class=
"tw-text-2xl"
>
Role: {{role}}
</h3>
</header>
src/app/+admin/layout/feature/ui/Components/header/header.component.ts
View file @
945c4ad3
import
{
CommonModule
}
from
'@angular/common'
;
import
{
ChangeDetectionStrategy
,
Component
,
OnInit
}
from
'@angular/core'
;
import
{
ChangeDetectionStrategy
,
Component
,
Input
,
OnInit
}
from
'@angular/core'
;
import
{
NzLayoutModule
}
from
'ng-zorro-antd/layout'
;
@
Component
({
selector
:
'meu-header'
,
selector
:
'meu-
admin-
header'
,
standalone
:
true
,
imports
:
[
CommonModule
,
NzLayoutModule
],
templateUrl
:
'./header.component.html'
,
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
HeaderComponent
implements
OnInit
{
@
Input
()
role
=
''
;
ngOnInit
():
void
{}
}
src/app/+admin/layout/feature/ui/layout.component.html
View file @
945c4ad3
<nz-layout>
<nz-sider
nzCollapsible
[
(
nzCollapsed
)]="
isCollapsed
"
[
nzTrigger
]="
null
"
>
<nz-sider
nzCollapsible
[
nzTrigger
]="
null
"
>
<div
class=
"logo"
></div>
<ul
nz-menu
nzTheme=
"dark"
nzMode=
"inline"
>
<li
nz-submenu
nzTitle=
"Quản lí công việc"
nzIcon=
"user"
>
<ul>
<li
nz-menu-item
routerLink=
"/admin/job-management/jobLayout"
>
Danh sách công việc
</li>
<li
nz-menu-item
routerLink=
"/admin/job-management/jobForm"
>
Thêm công việc
</li>
</ul>
<li
nz-menu-item
routerLink=
"/admin/job-management/Job"
>
Danh sách công việc
</li>
<li
nz-menu-item
(
click
)="
logout
()"
>
<span
nz-icon
nzType=
"logout"
nzTheme=
"outline"
></span>
Đăng xuất
</li>
<li
nz-menu-item
nzIcon=
"close"
(
click
)="
logout
()"
>
Đăng xuất
</li>
</ul>
</nz-sider>
<nz-layout>
<meu-header></meu-header>
<nz-header>
<span
class=
"trigger"
nz-icon
[
nzType
]="
isCollapsed
?
'
menu-unfold
'
:
'
menu-fold
'"
(
click
)="
isCollapsed =
!isCollapsed"
></span>
</nz-header>
<meu-admin-header
role=
{{role}}
></meu-admin-header>
<nz-content>
<router-outlet></router-outlet>
</nz-content>
...
...
src/app/+admin/layout/feature/ui/layout.component.ts
View file @
945c4ad3
import
{
RouterLink
,
RouterModule
,
RouterOutlet
}
from
'@angular/router'
;
import
{
defaultUrlMatcher
,
RouterLink
,
RouterModule
,
RouterOutlet
}
from
'@angular/router'
;
import
{
ChangeDetectionStrategy
,
Component
,
OnInit
}
from
'@angular/core'
;
import
{
NzLayoutModule
}
from
'ng-zorro-antd/layout'
;
...
...
@@ -33,9 +33,10 @@ import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
AdminLayoutComponent
implements
OnInit
{
role
=
localStorage
.
getItem
(
'role'
);
constructor
()
{}
isCollapsed
=
false
;
ngOnInit
():
void
{
}
ngOnInit
():
void
{
}
logout
()
{
localStorage
.
clear
();
window
.
location
.
href
=
'/login'
;
...
...
src/app/+home/component/JobCard/JobCard.component.html
0 → 100644
View file @
945c4ad3
<nz-card
nzHoverable
style=
"width:240px"
[
nzCover
]="
coverTemplate
"
>
<nz-card-meta
nzTitle=
"Europe Street beat"
nzDescription=
"www.instagram.com"
></nz-card-meta>
</nz-card>
<ng-template
#
coverTemplate
>
<img
alt=
"example"
src=
"https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png"
/>
</ng-template>
src/app/+home/component/JobCard/JobCard.component.ts
0 → 100644
View file @
945c4ad3
import
{
ChangeDetectionStrategy
,
Component
}
from
"@angular/core"
;
import
{
NzCardModule
}
from
"ng-zorro-antd/card"
;
@
Component
({
selector
:
'job-card'
,
templateUrl
:
'./JobCard.component.html'
,
imports
:
[
NzCardModule
],
standalone
:
true
,
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
JobCardComponent
{
}
src/app/+home/component/JobListCard/JobListCard.component.html
0 → 100644
View file @
945c4ad3
<nz-divider
nzOrientation=
"left"
nzText=
"Vertical"
></nz-divider>
<div
nz-row
[
nzGutter
]="[
16
,
24
]"
ngFor=
"let index of listOfJob"
>
<job-card></job-card>
</div>
src/app/+home/component/JobListCard/JobListCard.component.ts
0 → 100644
View file @
945c4ad3
import
{
ChangeDetectionStrategy
,
Component
}
from
"@angular/core"
;
import
{
JobCardComponent
}
from
"../JobCard/JobCard.component"
;
import
{
NzDividerModule
}
from
"ng-zorro-antd/divider"
;
import
{
NzGridModule
}
from
"ng-zorro-antd/grid"
;
import
{
JobModel
}
from
"../../../+admin/data-access/model/jobModel.model"
;
@
Component
({
selector
:
'app-job-card'
,
templateUrl
:
'./JobListCard.component.html'
,
imports
:
[
NzDividerModule
,
NzGridModule
,
JobCardComponent
,
],
standalone
:
true
,
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
JobListCardComponent
{
listOfJob
:
JobModel
[]
=
[];
}
src/app/+home/feature/home.component.html
View file @
945c4ad3
<div>
home
</div>
<meu-home-header></meu-home-header>
<meu-home-footer></meu-home-footer>
src/app/+home/feature/home.component.ts
View file @
945c4ad3
...
...
@@ -7,6 +7,8 @@ import { NzMenuModule } from 'ng-zorro-antd/menu';
import
{
NzIconModule
}
from
'ng-zorro-antd/icon'
;
import
{
HeaderComponent
}
from
'../../+shell/ui/components/header/feature/header.component'
;
import
{
FooterComponent
}
from
"../../+shell/ui/components/footer/feature/footer.component"
;
import
{
HeaderHomeComponent
}
from
'../layout/feature/Components/header/header.component'
;
import
{
FooterHomeComponent
}
from
'../layout/feature/Components/footer/footer.component'
;
@
Component
({
...
...
@@ -19,8 +21,8 @@ import { FooterComponent } from "../../+shell/ui/components/footer/feature/foote
NzBreadCrumbModule
,
NzMenuModule
,
NzIconModule
,
HeaderComponent
,
FooterComponent
Header
Home
Component
,
Footer
Home
Component
],
templateUrl
:
'./home.component.html'
,
styleUrls
:
[
'./home.component.scss'
],
...
...
src/app/+home/layout/feature/Components/footer/footer.component.html
0 → 100644
View file @
945c4ad3
<nz-footer>
<footer
class=
"tw-bg-gray-800 tw-py-8"
>
<div
class=
"tw-container tw-mx-auto"
>
<div
class=
"tw-flex tw-justify-between tw-items-center tw-px-4"
>
<!-- Tên công ty -->
<div
class=
"tw-text-2xl tw-font-bold"
>
MeU Solution
</div>
<!-- Liên kết menu -->
<div
class=
"tw-hidden tw-lg:flex"
>
<ul
class=
"tw-flex tw-space-x-6"
>
<li><a
href=
"/about"
class=
"tw-text-gray-400 hover:tw-text-white"
>
Giới thiệu
</a></li>
<li><a
href=
"/services"
class=
"tw-text-gray-400 hover:tw-text-white"
>
Dịch vụ
</a></li>
<li><a
href=
"/contact"
class=
"tw-text-gray-400 hover:tw-text-white"
>
Liên hệ
</a></li>
<li><a
href=
"/blog"
class=
"tw-text-gray-400 hover:tw-text-white"
>
Blog
</a></li>
</ul>
</div>
<!-- Mạng xã hội -->
<div
class=
"tw-flex tw-space-x-4"
>
<a
href=
"https://facebook.com"
target=
"_blank"
class=
"tw-text-gray-400 hover:tw-text-white"
><i
class=
"fa fa-facebook"
></i></a>
<a
href=
"https://twitter.com"
target=
"_blank"
class=
"tw-text-gray-400 hover:tw-text-white"
><i
class=
"fa fa-twitter"
></i></a>
<a
href=
"https://instagram.com"
target=
"_blank"
class=
"tw-text-gray-400 hover:tw-text-white"
><i
class=
"fa fa-instagram"
></i></a>
</div>
</div>
<!-- Bản quyền và địa chỉ -->
<div
class=
"tw-border-t tw-border-gray-700 tw-mt-6 tw-pt-6 tw-text-center"
>
<p
class=
"tw-text-sm"
>
©
2024 Công ty ABC. Tất cả quyền lợi được bảo lưu.
</p>
<p
class=
"tw-text-sm"
>
Địa chỉ: 123 Đường ABC, Quận 1, Thành phố Hồ Chí Minh, Việt Nam
</p>
</div>
</div>
</footer>
</nz-footer>
src/app/+home/layout/feature/Components/footer/footer.component.ts
0 → 100644
View file @
945c4ad3
import
{
CommonModule
}
from
'@angular/common'
;
import
{
ChangeDetectionStrategy
,
Component
,
OnInit
}
from
'@angular/core'
;
import
{
NzIconModule
}
from
'ng-zorro-antd/icon'
;
import
{
NzLayoutModule
}
from
'ng-zorro-antd/layout'
;
@
Component
({
selector
:
'meu-home-footer'
,
standalone
:
true
,
imports
:
[
CommonModule
,
NzLayoutModule
,
NzIconModule
],
templateUrl
:
'./footer.component.html'
,
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
FooterHomeComponent
implements
OnInit
{
ngOnInit
():
void
{}
}
src/app/+home/layout/feature/Components/header/header.component.html
0 → 100644
View file @
945c4ad3
<header
class=
"tw-bg-gray-900 tw-py-4"
>
<div
class=
"tw-container tw-mx-auto tw-flex tw-justify-between tw-items-center tw-px-4"
>
<div
class=
"tw-text-3xl tw-font-bold"
>
<a
href=
"/"
class=
"hover:tw-text-gray-400"
>
MeU Solution
</a>
</div>
</div>
<nav
class=
"tw-bg-gray-900 tw-py-2"
>
<div
class=
"tw-container tw-mx-auto"
>
<ul
class=
"tw-flex tw-space-x-8 tw-justify-center"
>
<li><a
href=
"/#"
class=
"tw-text-gray-300 hover:tw-text-white"
>
Giới thiệu
</a></li>
<li><a
href=
"/#"
class=
"tw-text-gray-300 hover:tw-text-white"
>
Dịch vụ
</a></li>
<li><a
href=
"/#"
class=
"tw-text-gray-300 hover:tw-text-white"
>
Liên hệ
</a></li>
<li><a
href=
"/#"
class=
"tw-text-gray-300 hover:tw-text-white"
>
Blog
</a></li>
</ul>
</div>
</nav>
</header>
src/app/+home/layout/feature/Components/header/header.component.ts
0 → 100644
View file @
945c4ad3
import
{
CommonModule
}
from
'@angular/common'
;
import
{
ChangeDetectionStrategy
,
Component
,
OnInit
}
from
'@angular/core'
;
import
{
NzLayoutModule
}
from
'ng-zorro-antd/layout'
;
@
Component
({
selector
:
'meu-home-header'
,
standalone
:
true
,
imports
:
[
CommonModule
,
NzLayoutModule
],
templateUrl
:
'./header.component.html'
,
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
HeaderHomeComponent
implements
OnInit
{
ngOnInit
():
void
{}
}
src/app/+login/data-access/Services/A
piService.s
ervice.ts
→
src/app/+login/data-access/Services/A
uth.S
ervice.ts
View file @
945c4ad3
import
{
Injectable
}
from
'@angular/core'
;
import
{
HttpClient
,
HttpHeaders
}
from
'@angular/common/http'
;
import
{
Observable
}
from
'rxjs'
;
import
{
Observable
,
tap
}
from
'rxjs'
;
import
{
environment
}
from
'../../../../environments/environment.development'
;
import
{
Router
}
from
'@angular/router'
;
@
Injectable
({
providedIn
:
'root'
,
})
export
class
AuthService
{
private
apiUrl
=
environment
.
API_DOMAIN
+
'/login'
;
constructor
(
private
http
:
HttpClient
)
{}
constructor
(
private
http
:
HttpClient
,
private
router
:
Router
)
{}
login
(
username
:
string
,
password
:
string
):
Observable
<
any
>
{
const
headers
=
new
HttpHeaders
({
'Content-Type'
:
'application/json'
});
const
body
=
{
username
,
password
};
return
this
.
http
.
post
<
any
>
(
this
.
apiUrl
,
body
,
{
headers
}).
pipe
(
tap
((
response
)
=>
{
localStorage
.
setItem
(
'token'
,
response
.
responseData
.
token
);
localStorage
.
setItem
(
'expirationTime'
,
response
.
responseData
.
expirationTime
);
localStorage
.
setItem
(
'role'
,
response
.
responseData
.
role
);
})
);
}
logout
():
void
{
localStorage
.
removeItem
(
'token'
);
localStorage
.
removeItem
(
'expirationTime'
);
localStorage
.
removeItem
(
'role'
);
this
.
router
.
navigate
([
'/login'
]);
}
isLoggedIn
():
boolean
{
const
token
=
localStorage
.
getItem
(
'token'
);
if
(
token
)
{
return
true
;
}
return
false
;
}
loginSussces
():
void
{
this
.
getUserRole
()
===
"admin"
?
this
.
router
.
navigate
([
'/admin'
])
:
this
.
router
.
navigate
([
'/home'
]);
}
return
this
.
http
.
post
<
any
>
(
this
.
apiUrl
,
body
,
{
headers
});
getUserRole
():
string
|
null
{
return
localStorage
.
getItem
(
'role'
);
}
}
src/app/+login/data-access/guard/admin.guard.ts
View file @
945c4ad3
...
...
@@ -11,7 +11,7 @@ export class AdminGuard implements CanActivate {
if
(
role
===
'admin'
)
{
return
true
;
}
else
{
this
.
router
.
navigate
([
'/
login'
]);
// chuyển đến trang lỗi không có quyền. cho bắt đăng nhập với quyên admin
this
.
router
.
navigate
([
'/
home'
]);
return
false
;
}
}
...
...
src/app/+login/data-access/guard/auth.guard.ts
View file @
945c4ad3
...
...
@@ -9,12 +9,16 @@ export class AuthGuard implements CanActivate {
canActivate
():
boolean
{
const
token
=
localStorage
.
getItem
(
'token'
);
if
(
token
)
{
this
.
router
.
navigate
([
'/
adm
in'
]);
if
(
!
token
)
{
this
.
router
.
navigate
([
'/
log
in'
]);
return
false
;
}
else
{
const
currentRoute
=
this
.
router
.
url
;
if
(
currentRoute
===
'/login'
)
{
this
.
router
.
navigate
([
'/home'
]);
return
false
;
}
return
true
;
}
}
}
src/app/+login/data-access/guard/login.guard.ts
0 → 100644
View file @
945c4ad3
import
{
Injectable
}
from
'@angular/core'
;
import
{
CanActivate
,
Router
}
from
'@angular/router'
;
import
{
AuthService
}
from
'../Services/Auth.Service'
;
@
Injectable
({
providedIn
:
'root'
,
})
export
class
LoginGuard
implements
CanActivate
{
constructor
(
private
_service
:
AuthService
,
private
_router
:
Router
)
{}
canActivate
():
boolean
{
if
(
this
.
_service
.
isLoggedIn
())
{
this
.
_router
.
navigate
([
'/home'
]);
return
false
;
}
return
true
;
}
}
src/app/+login/feature/login.component.html
View file @
945c4ad3
...
...
@@ -15,19 +15,7 @@
</nz-input-group>
</nz-form-control>
</nz-form-item>
<div
nz-row
class=
"login-form-margin"
>
<div
nz-col
[
nzSpan
]="
12
"
>
<label
nz-checkbox
formControlName=
"remember"
>
<span>
Remember me
</span>
</label>
</div>
<div
nz-col
[
nzSpan
]="
12
"
>
<a
class=
"login-form-forgot"
>
Forgot password
</a>
</div>
</div>
<p
*
ngIf=
"MgsError"
class=
"error-message tw-text-center"
>
{{MgsError}}
</p>
<button
nz-button
class=
"login-form-button login-form-margin"
[
nzType
]="'
primary
'"
>
Log in
</button>
<div
class=
"text-center mt-4"
>
Or
<a>
register now!
</a>
</div>
</form>
</div>
src/app/+login/feature/login.component.ts
View file @
945c4ad3
...
...
@@ -11,8 +11,8 @@ import { NzAlertModule } from 'ng-zorro-antd/alert';
import
{
CommonModule
}
from
'@angular/common'
;
import
{
FormBuilder
,
FormGroup
,
FormsModule
,
ReactiveFormsModule
,
Validators
}
from
'@angular/forms'
;
import
{
catchError
,
finalize
,
Observable
,
of
,
tap
}
from
'rxjs'
;
import
{
AuthService
}
from
'../data-access/Services/ApiService.service'
;
import
{
response
}
from
'express'
;
import
{
AuthService
}
from
'../data-access/Services/Auth.Service'
;
@
Component
({
selector
:
'meu-login'
,
standalone
:
true
,
...
...
@@ -44,30 +44,22 @@ export class LoginComponent implements OnInit {
});
}
ngOnInit
()
{}
saveInfo
(
res
:
any
)
{
localStorage
.
setItem
(
'token'
,
res
.
responseData
.
token
);
localStorage
.
setItem
(
'expirationTime'
,
res
.
responseData
.
expirationTime
);
localStorage
.
setItem
(
'role'
,
res
.
responseData
.
role
);
}
onSubmit
()
{
if
(
!
this
.
loginForm
.
valid
)
{
this
.
MgsError
=
"Vui lòng nhập th
ố
ng tin đăng nhập"
;
this
.
MgsError
=
"Vui lòng nhập th
ô
ng tin đăng nhập"
;
return
;
}
console
.
log
(
this
.
loginForm
.
value
.
userName
,
this
.
loginForm
.
value
.
password
);
this
.
authService
.
login
(
this
.
loginForm
.
value
.
userName
,
this
.
loginForm
.
value
.
password
).
pipe
(
tap
((
res
)
=>
{
// không ảnh hưởng đến data trên observable
this
.
saveInfo
(
res
);
window
.
location
.
href
=
'/admin'
;
}),
catchError
((
err
)
=>
{
this
.
MgsError
=
err
.
message
;
console
.
log
(
this
.
MgsError
);
console
.
log
(
err
);
return
of
(
null
);
}),
finalize
(()
=>
{
// gọi ra khi observable hoàn tất
finalize
(()
=>
{
if
(
this
.
authService
.
isLoggedIn
())
this
.
authService
.
loginSussces
();
console
.
log
(
'Login request completed'
);
})
).
subscribe
();
...
...
src/app/+shell/feature/shell.routes.ts
View file @
945c4ad3
...
...
@@ -3,6 +3,7 @@ import { LayoutComponent } from '../ui/layout.component';
import
{
LoginComponent
}
from
'../../+login/feature/login.component'
;
import
{
AuthGuard
}
from
'../../+login/data-access/guard/auth.guard'
;
import
{
AdminGuard
}
from
'../../+login/data-access/guard/admin.guard'
;
import
{
LoginGuard
}
from
'../../+login/data-access/guard/login.guard'
;
export
const
shellRoutes
:
Routes
=
[
{
...
...
@@ -16,7 +17,7 @@ export const shellRoutes: Routes = [
},
{
path
:
'home'
,
canActivate
:
[],
//not have guard yet, set up later
canActivate
:
[],
loadChildren
:
()
=>
import
(
'../../+home/home.routes'
),
},
],
...
...
@@ -34,6 +35,13 @@ export const shellRoutes: Routes = [
{
path
:
'login'
,
component
:
LoginComponent
,
canActivate
:
[
AuthGuard
],
children
:
[
{
path
:
''
,
canActivate
:
[
LoginGuard
],
loadChildren
:
()
=>
import
(
'../../+login/login.routes'
),
}
]
},
];
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment