Skip to content

Commit 31214f4

Browse files
authored
Merge pull request #146 from CapstoneProjectCMC/feature/sap-service-and-payment
Feature/sap service and payment
2 parents 021636b + f4f2f03 commit 31214f4

File tree

43 files changed

+1647
-147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1647
-147
lines changed

src/app/app.routes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export const routes: Routes = [
144144
import('./features/organization/organization.module').then(
145145
(m) => m.OrganizationModule
146146
),
147-
data: { roles: ['ROLE_ADMIN'] },
147+
data: { roles: ['ADMIN'] },
148148
canActivate: [RoleGuard],
149149
},
150150
],

src/app/core/guards/router-protected/role.guard.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ export class RoleGuard implements CanActivate {
2727
| Observable<boolean | UrlTree>
2828
| Promise<boolean | UrlTree> {
2929
const expectedRoles = next.data['roles'] as string[]; // lấy roles từ route
30-
const userRole = decodeJWT(localStorage.getItem('token') ?? '')?.payload
31-
.scope;
30+
const userRoles = decodeJWT(localStorage.getItem('token') ?? '')?.payload
31+
.roles;
3232

3333
if (!expectedRoles || expectedRoles.length === 0) {
3434
return true; // không yêu cầu role -> cho vào
3535
}
3636

37-
if (expectedRoles.includes(userRole)) {
37+
if (userRoles && userRoles.some((role) => expectedRoles.includes(role))) {
3838
return true;
3939
} else {
4040
sendNotification(
@@ -60,7 +60,7 @@ export class RoleGuard implements CanActivate {
6060
import('./features/service-payment/service-and-payment.module').then(
6161
(m) => m.ServiceAndPaymentModule
6262
),
63-
data: { roles: ['ROLE_ADMIN'] },
63+
data: { roles: ['ADMIN'] },
6464
canActivate: [RoleGuard],
6565
},
6666

src/app/core/models/organization.model.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { IPaginationResponse } from './api-response';
2+
import { UserBasicInfo } from './exercise.model';
3+
14
export type OrganizationInfo = {
25
id: string;
36
name: string;
@@ -9,3 +12,68 @@ export type OrganizationInfo = {
912
logoUrl: string | null;
1013
status: number; // 0 Active, 1 Inactive, 2 Pending
1114
};
15+
16+
export type CreateOrgRequest = {
17+
name: string;
18+
description: string;
19+
email: string;
20+
phone: string;
21+
address: string;
22+
status: string;
23+
logo: File;
24+
};
25+
26+
//Search response
27+
export type MemberResponse = {
28+
user: UserBasicInfo;
29+
role: string;
30+
active: boolean;
31+
};
32+
33+
export type BlockResponse = {
34+
id: string;
35+
orgId: string;
36+
name: string;
37+
code: string;
38+
description: string;
39+
createdAt: string;
40+
updatedAt: string;
41+
members: IPaginationResponse<MemberResponse[]>;
42+
};
43+
44+
export type OrganizationResponse = {
45+
id: string;
46+
name: string;
47+
description: string;
48+
logoUrl: string | null;
49+
email: string;
50+
phone: string;
51+
address: string;
52+
status: string;
53+
createdAt: string;
54+
updatedAt: string;
55+
blocks: IPaginationResponse<BlockResponse[]>;
56+
};
57+
58+
//filter
59+
export type FilterOrgs = {
60+
q?: string;
61+
status?: string;
62+
includeBlocks?: boolean;
63+
blocksPage?: number;
64+
blocksSize?: number;
65+
membersPage?: number;
66+
membersSize?: number;
67+
activeOnlyMembers?: boolean;
68+
includeUnassigned?: boolean;
69+
};
70+
71+
//edit basic info
72+
export type EditOrgRequest = {
73+
description?: string;
74+
email?: string;
75+
phone?: string;
76+
address?: string;
77+
status?: string;
78+
logo?: File;
79+
};

src/app/core/models/post.models.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface PostCardInfo {
1313
downvote: number;
1414
public: boolean;
1515
allowComment: boolean;
16+
isSaved?: boolean;
1617
}
1718

1819
export interface Tag {
@@ -164,3 +165,13 @@ export interface PostDataCreateRequest {
164165
isLectureVideo: boolean;
165166
isTextbook: boolean;
166167
}
168+
169+
export type SavedPostResponse = {
170+
id: string;
171+
saveAt: string;
172+
post: {
173+
id: string;
174+
postId: string;
175+
title: string;
176+
};
177+
};

src/app/core/router-manager/horizontal-menu.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { SidebarItem } from '../models/data-handle';
22

3-
export function getNavHorizontalItems(role: string): SidebarItem[] {
4-
const auth_lv1 = ['ROLE_ADMIN', 'ROLE_TEACHER'];
5-
const auth_lv2 = ['ROLE_ADMIN'];
3+
export function getNavHorizontalItems(roles: string[]): SidebarItem[] {
4+
const auth_lv1 = ['ADMIN', 'TEACHER'];
5+
const auth_lv2 = ['ADMIN'];
6+
console.log(roles);
67

78
return [
89
{
@@ -28,20 +29,21 @@ export function getNavHorizontalItems(role: string): SidebarItem[] {
2829
path: 'conversations/chat',
2930
label: 'Tin nhắn',
3031
icon: 'fas fa-comments',
32+
isVisible: !(roles.length !== 0),
3133
},
3234
{
3335
id: 'statistics',
3436
path: '/statistics',
3537
label: 'Thống kê',
3638
icon: 'fas fa-chart-bar',
37-
isVisible: !auth_lv2.includes(role),
39+
isVisible: !roles.includes(auth_lv2[0]),
3840
},
3941
{
4042
id: 'management',
4143
path: 'management/admin',
4244
label: 'Admin quản lý',
4345
icon: 'fas fa-user-shield',
44-
isVisible: !auth_lv2.includes(role),
46+
isVisible: !roles.includes(auth_lv2[0]),
4547
},
4648
{
4749
id: 'payment',
@@ -51,10 +53,10 @@ export function getNavHorizontalItems(role: string): SidebarItem[] {
5153
},
5254
{
5355
id: 'organization ',
54-
path: '/organization/list',
56+
path: '/organization/orgs-list',
5557
label: 'Tổ chức',
5658
icon: 'fa-solid fa-building-user',
57-
isVisible: !auth_lv2.includes(role),
59+
isVisible: !roles.includes(auth_lv2[0]),
5860
},
5961
];
6062
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { SidebarItem } from '../../models/data-handle';
2+
3+
export function sidebarOrgRouter(roles: string[]): SidebarItem[] {
4+
return [
5+
{
6+
id: 'list-orgs',
7+
path: '/organization/orgs-list',
8+
label: 'Nạp tiền',
9+
icon: 'fa-solid fa-tasks',
10+
},
11+
];
12+
}

src/app/core/router-manager/vetical-menu-dynamic/post-vertical-menu.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { SidebarItem } from '../../models/data-handle';
22

3-
export function sidebarPosts(role: string): SidebarItem[] {
3+
export function sidebarPosts(roles: string[]): SidebarItem[] {
44
return [
55
{
6-
id: 'populat',
7-
path: 'exercise/popular',
8-
label: 'Bài viết phổ biến',
6+
id: 'saved-posts',
7+
path: '/post-features/saved-posts-list',
8+
label: 'Bài viết đã lưu',
99
icon: 'fas fa-file-alt',
1010
},
1111
{
1212
id: 'exercise',
13-
path: '/post-management/post-list',
13+
path: '/post-features/post-list',
1414
label: 'Quản lý bài viết',
1515
icon: 'fas fa-tasks',
1616
},
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Injectable } from '@angular/core';
2+
import { ApiMethod } from '../config-service/api.methods';
3+
import { ApiResponse, IPaginationResponse } from '../../models/api-response';
4+
import { API_CONFIG } from '../config-service/api.enpoints';
5+
import {
6+
CreateOrgRequest,
7+
EditOrgRequest,
8+
FilterOrgs,
9+
OrganizationInfo,
10+
OrganizationResponse,
11+
} from '../../models/organization.model';
12+
import { PostResponse } from '../../models/post.models';
13+
14+
@Injectable({
15+
providedIn: 'root',
16+
})
17+
export class OrganizationService {
18+
constructor(private api: ApiMethod) {}
19+
20+
createOrg(dataCreate: CreateOrgRequest) {
21+
const { logo, ...otherData } = dataCreate;
22+
return this.api.postWithFormData<ApiResponse<null>>(
23+
API_CONFIG.ENDPOINTS.POST.CREATE_ORGANIZATION,
24+
otherData, // các field string
25+
{ logo }
26+
);
27+
}
28+
29+
searchOrgsFilter(page: number, size: number, search?: FilterOrgs) {
30+
const endpoint = API_CONFIG.ENDPOINTS.GET.SEARCH_ORGS_FILTER(
31+
page,
32+
size,
33+
search ? search : null
34+
);
35+
36+
return this.api.get<
37+
ApiResponse<IPaginationResponse<OrganizationResponse[]>>
38+
>(endpoint);
39+
}
40+
41+
getOrgDetails(orgId: string) {
42+
return this.api.get<ApiResponse<OrganizationInfo>>(
43+
API_CONFIG.ENDPOINTS.GET.GET_ORG_DETAILS_BY_ID(orgId)
44+
);
45+
}
46+
47+
editOrg(orgId: string, data: EditOrgRequest) {
48+
return this.api.put<ApiResponse<null>>(
49+
API_CONFIG.ENDPOINTS.PUT.EDIT_ORG(orgId),
50+
data
51+
);
52+
}
53+
54+
deleteOrg(orgId: string) {
55+
return this.api.delete<ApiResponse<null>>(
56+
API_CONFIG.ENDPOINTS.DELETE.DELETE_ORG(orgId)
57+
);
58+
}
59+
}

src/app/core/services/api-service/playground.service.ts

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/app/core/services/api-service/post.service.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
CreatePostRequest,
1212
postData,
1313
PostResponse,
14+
SavedPostResponse,
1415
} from '../../models/post.models';
1516

1617
@Injectable({
@@ -142,4 +143,23 @@ export class PostService {
142143
API_CONFIG.ENDPOINTS.DELETE.DELETE_POST(id)
143144
);
144145
}
146+
147+
savePost(postId: string) {
148+
return this.api.post<ApiResponse<null>>(
149+
API_CONFIG.ENDPOINTS.POST.SAVE_POST(postId),
150+
null
151+
);
152+
}
153+
154+
unSavePost(postId: string) {
155+
return this.api.delete<ApiResponse<null>>(
156+
API_CONFIG.ENDPOINTS.POST.SAVE_POST(postId)
157+
);
158+
}
159+
160+
getSavedPosts(page: number, size: number) {
161+
return this.api.get<ApiResponse<IPaginationResponse<SavedPostResponse[]>>>(
162+
API_CONFIG.ENDPOINTS.GET.GET_SAVED_POSTS(page, size)
163+
);
164+
}
145165
}

0 commit comments

Comments
 (0)