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
6 months ago
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>
This diff is collapsed.
Click to expand it.
src/app/+admin/Management/Job/Job.component.scss
0 → 100644
View file @
945c4ad3
This diff is collapsed.
Click to expand it.
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
}
This diff is collapsed.
Click to expand it.
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
),
},
];
...
...
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
();
}
}
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
()
{}
}
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
();
}
}
This diff is collapsed.
Click to expand it.
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'
),
},
]
}
...
...
This diff is collapsed.
Click to expand it.
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
;
...
...
This diff is collapsed.
Click to expand it.
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
});
}
}
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
{}
}
This diff is collapsed.
Click to expand it.
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>
...
...
This diff is collapsed.
Click to expand it.
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'
;
...
...
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
{
}
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
[]
=
[];
}
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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'
],
...
...
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
{}
}
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
{}
}
This diff is collapsed.
Click to expand it.
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'
);
}
}
This diff is collapsed.
Click to expand it.
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
;
}
}
...
...
This diff is collapsed.
Click to expand it.
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
;
}
}
}
This diff is collapsed.
Click to expand it.
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
;
}
}
This diff is collapsed.
Click to expand it.
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>
This diff is collapsed.
Click to expand it.
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
();
...
...
This diff is collapsed.
Click to expand it.
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'
),
}
]
},
];
This diff is collapsed.
Click to expand it.
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