From e73968b92056de0aa1251746345d55778c046924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B4=20Quang=20=C4=90=E1=BB=A9c?= Date: Mon, 1 Sep 2025 20:29:31 +0700 Subject: [PATCH] fix create resoure learning --- src/app/core/models/post.models.ts | 9 + .../services/api-service/resource.service.ts | 55 +--- .../resource-create/resource-create.html | 82 ----- .../resource-create/resource-create.scss | 289 +++++++++--------- .../pages/resource-create/resource-create.ts | 79 +---- .../resource-detail/resource-detail.html | 4 +- .../pages/resource-detail/resource-detail.ts | 8 +- .../pages/resource-list/resource-list.html | 7 +- .../pages/resource-list/resource-list.ts | 36 ++- .../resource-card/resource-card.html | 4 +- .../my-shared/resource-card/resource-card.ts | 29 +- src/app/shared/utils/authenRoleActions.ts | 4 +- 12 files changed, 255 insertions(+), 351 deletions(-) diff --git a/src/app/core/models/post.models.ts b/src/app/core/models/post.models.ts index c334af0d..8c8dad19 100644 --- a/src/app/core/models/post.models.ts +++ b/src/app/core/models/post.models.ts @@ -155,3 +155,12 @@ export type PostResponse = { upvoteCount: number; downvoteCount: number; }; + +//post-create +export interface PostDataCreateRequest { + file: File; + description: string; + tags: string[]; + isLectureVideo: boolean; + isTextbook: boolean; +} diff --git a/src/app/core/services/api-service/resource.service.ts b/src/app/core/services/api-service/resource.service.ts index a1da3963..fb98e712 100644 --- a/src/app/core/services/api-service/resource.service.ts +++ b/src/app/core/services/api-service/resource.service.ts @@ -8,6 +8,7 @@ import { } from '../../models/api-response'; import { MediaResource, ResourceData, Tag } from '../../models/resource.model'; import { API_CONFIG } from '../config-service/api.enpoints'; +import { PostDataCreateRequest } from '../../models/post.models'; @Injectable({ providedIn: 'root', @@ -52,51 +53,25 @@ export class ResourceService { API_CONFIG.ENDPOINTS.GET.GET_FILE_BY_ID(id) ); } - addResource(postData: { - file: File; - category: number; - description: string; - tags: string[]; - isLectureVideo: boolean; - isTextbook: boolean; - orgId?: string; - associatedResourceIds?: string[]; - thumbnailUrl?: string; - }) { - const formData = new FormData(); - - if (postData.file) { - formData.append('file', postData.file); - } - - if (postData.category !== null) { - formData.append('category', postData.category.toString()); - } - - formData.append('description', postData.description || ''); - formData.append('isLectureVideo', String(postData.isLectureVideo)); - formData.append('isTextbook', String(postData.isTextbook)); - if (postData.orgId) { - formData.append('orgId', postData.orgId); - } - - if (postData.thumbnailUrl) { - formData.append('thumbnailUrl', postData.thumbnailUrl); - } + addResource(postData: PostDataCreateRequest) { + const { file, description, tags, isLectureVideo, isTextbook } = postData; - // Tags array - postData.tags?.forEach((tag, i) => formData.append(`tags[${i}]`, tag)); + // data: phần dữ liệu thông thường (không phải file) + const data: Record = { + description, + tags: JSON.stringify(tags), // stringify array để backend parse + isLectureVideo: String(isLectureVideo), + isTextbook: String(isTextbook), + }; - // Associated resources array - postData.associatedResourceIds?.forEach((id, i) => - formData.append(`associatedResourceIds[${i}]`, id) - ); + // files: phần file + const files: File = file; - return this.api.post>( + return this.api.postWithFormData>( API_CONFIG.ENDPOINTS.POST.ADD_FILE, - formData, - true + data, + files ); } diff --git a/src/app/features/resource-learning/pages/resource-create/resource-create.html b/src/app/features/resource-learning/pages/resource-create/resource-create.html index 1ade97ee..326b6537 100644 --- a/src/app/features/resource-learning/pages/resource-create/resource-create.html +++ b/src/app/features/resource-learning/pages/resource-create/resource-create.html @@ -1,37 +1,5 @@
-
- -
-
- -
@@ -83,54 +49,6 @@
-
-
+
{ - this.resources = res.result.data; + const newData = res.result.data; + const { currentPage, totalPages } = res.result; + + // Gán data + this.resources = append ? [...this.resources, ...newData] : newData; + + // Kiểm tra còn trang tiếp theo không + this.hasMore = currentPage < totalPages; + + this.isLoading = false; + this.isLoadingMore = false; }, - error(err) { - console.log(err); + error: (err) => { + console.error(err); + this.isLoading = false; + this.isLoadingMore = false; }, }); } + // ================== Load Next Page ================== + loadNextPage() { + if (this.isLoadingMore || !this.hasMore) return; + + this.pageIndex++; + this.fetchDataResource(true); // append thêm dữ liệu + } + // ================== Delete ================== getDeleteHandler(resourceId: string): () => void { return () => this.deleteResource(resourceId); diff --git a/src/app/shared/components/my-shared/resource-card/resource-card.html b/src/app/shared/components/my-shared/resource-card/resource-card.html index 618442b5..362495d2 100644 --- a/src/app/shared/components/my-shared/resource-card/resource-card.html +++ b/src/app/shared/components/my-shared/resource-card/resource-card.html @@ -44,7 +44,7 @@ *ngIf="isFileType('video') && resource.duration" class="media-duration" > - {{ formatDuration(resource.duration) }} + {{ resource.duration }}
{{ resource.viewCount || 0 }} @@ -75,7 +75,7 @@

{{ resource.fileName }}

-
+
diff --git a/src/app/shared/components/my-shared/resource-card/resource-card.ts b/src/app/shared/components/my-shared/resource-card/resource-card.ts index 2c7f4857..8cba7be3 100644 --- a/src/app/shared/components/my-shared/resource-card/resource-card.ts +++ b/src/app/shared/components/my-shared/resource-card/resource-card.ts @@ -9,6 +9,8 @@ import { import { CommonModule } from '@angular/common'; import { MediaResource } from '../../../../core/models/resource.model'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; +import { activeForMyContent } from '../../../utils/authenRoleActions'; +import { getUserRoles } from '../../../utils/userInfo'; @Component({ selector: 'app-resource-card', @@ -26,12 +28,35 @@ export class ResourceCardComponent implements OnChanges { @Output() delete = new EventEmitter(); safeUrl!: SafeResourceUrl; + roles = getUserRoles(); + + isActionActive = false; constructor(private sanitizer: DomSanitizer) {} + ngOnInit(): void { + if (this.resource?.userProfile) { + this.isActionActive = activeForMyContent( + this.resource.userProfile.username, + this.resource.userProfile.email, + this.roles.includes('ADMIN') + ); + } + } ngOnChanges(changes: SimpleChanges): void { - if (changes['resource'] && this.resource?.url) { - this.setSafeUrl(this.resource.url); + if (changes['resource'] && this.resource) { + if (this.resource.url) { + this.setSafeUrl(this.resource.url); + } + + // Cập nhật lại quyền khi resource thay đổi + if (this.resource.userProfile) { + this.isActionActive = activeForMyContent( + this.resource.userProfile.username, + this.resource.userProfile.email, + this.roles.includes('ADMIN') + ); + } } } diff --git a/src/app/shared/utils/authenRoleActions.ts b/src/app/shared/utils/authenRoleActions.ts index a66345bc..168e7983 100644 --- a/src/app/shared/utils/authenRoleActions.ts +++ b/src/app/shared/utils/authenRoleActions.ts @@ -10,8 +10,8 @@ export function activeForAdminAndTeacher(): boolean { } export function activeForMyContent( - usernameEqual: string, - emailEqual: string, + usernameEqual: string | null | undefined, + emailEqual: string | null | undefined, exception?: boolean ): boolean { const username = getUserName();