diff --git a/src/components/user-profile/Media.tsx b/src/components/user-profile/Media.tsx
index b9a1a3b..98f169d 100644
--- a/src/components/user-profile/Media.tsx
+++ b/src/components/user-profile/Media.tsx
@@ -17,7 +17,7 @@ export default function MediaCard({ data }: { data: MediaDto }) {
title: item.original_name,
description: `Size: ${(item.size / 1024).toFixed(2)} KB - Type: ${item.mime_type}`,
}));
-
+ // console.log("slides", listMedia);
return (
Media Assets
diff --git a/src/components/user-profile/UserMetaCard.tsx b/src/components/user-profile/UserMetaCard.tsx
index 52c8825..3bca2fc 100644
--- a/src/components/user-profile/UserMetaCard.tsx
+++ b/src/components/user-profile/UserMetaCard.tsx
@@ -1,28 +1,90 @@
"use client";
-// import React from "react";
-// import { useModal } from "../../hooks/useModal";
-// import { Modal } from "../ui/modal";
-// import Button from "../ui/button/Button";
-// import Input from "../form/input/InputField";
-// import Label from "../form/Label";
+
+import { useState, useRef } from "react";
import Image from "next/image";
import { UserMetaCardProps } from "@/interface/user";
+import { uploadMedia } from "@/service/mediaService";
export default function UserMetaCard({ data }: { data: UserMetaCardProps }) {
- // const { isOpen, openModal, closeModal } = useModal();
+ const [previewImage, setPreviewImage] = useState(
+ data.data?.profile?.avatar_url || "/images/no-images.jpg"
+ );
+ const [isUploading, setIsUploading] = useState(false);
+ const fileInputRef = useRef
(null);
+
+ const handleAvatarClick = () => {
+ if (!isUploading) {
+ fileInputRef.current?.click();
+ }
+ };
+
+ const handleFileChange = async (event: React.ChangeEvent) => {
+ const file = event.target.files?.[0];
+ if (!file) return;
+
+ try {
+ setIsUploading(true);
+ console.log("Selected file:", file);
+
+ const objectUrl = URL.createObjectURL(file);
+ setPreviewImage(objectUrl);
+
+ const uploadedMedia = await uploadMedia(file);
+ console.log("Upload thành công:", uploadedMedia);
+
+ } catch (error) {
+ console.error("Lỗi khi upload avatar:", error);
+ setPreviewImage(data.data?.profile?.avatar_url || "/images/no-images.jpg");
+ alert("Không thể tải ảnh lên. Vui lòng thử lại!");
+ } finally {
+ setIsUploading(false);
+ if (fileInputRef.current) {
+ fileInputRef.current.value = "";
+ }
+ }
+ };
+
return (
<>
-
+
+
+
+
+ {isUploading ? (
+
+ ) : (
+
+ )}
+
+
+
+
{data.data?.profile?.display_name || "Full Name"}
@@ -42,192 +104,9 @@ export default function UserMetaCard({ data }: { data: UserMetaCardProps }) {
- {/*
*/}
- {/*
*/}
- {/*
-
-
-
- Edit Personal Information
-
-
- Update your details to keep your profile up-to-date.
-
-
-
-
- */}
>
);
-}
+}
\ No newline at end of file
diff --git a/src/service/mediaService.ts b/src/service/mediaService.ts
index 3cde746..d6ccb61 100644
--- a/src/service/mediaService.ts
+++ b/src/service/mediaService.ts
@@ -1,10 +1,87 @@
import api from "@/config/config";
import { API } from "../../api";
import { payloadPresignedMedia } from "@/interface/media";
+import axios from "axios";
-export const apiGetCurrentUserMedia = async (payload: payloadPresignedMedia) => {
+export const apiGetCurrentUserMedia = async (
+ payload: payloadPresignedMedia,
+) => {
const response = await api.get(API.Media.PRESIGNED, {
params: payload,
});
return response?.data;
-};
\ No newline at end of file
+};
+
+export type FileType =
+ | "image"
+ | "video"
+ | "audio"
+ | "pdf"
+ | "docx"
+ | "text"
+ | "other";
+
+export const getFileType = (mime: string): FileType => {
+ if (!mime) return "other";
+
+ if (mime.startsWith("image/")) return "image";
+ if (mime.startsWith("video/")) return "video";
+ if (mime.startsWith("audio/")) return "audio";
+
+ if (mime === "application/pdf") return "pdf";
+
+ if (
+ mime ===
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+ )
+ return "docx";
+
+ if (mime.startsWith("text/")) return "text";
+
+ return "other";
+};
+
+type PreSignedResponse = {
+ token_id: string;
+ upload_url: string;
+ storage_key: string;
+ signed_headers: Record;
+};
+
+export const uploadFileToS3 = async (
+ file: File,
+ presigned: PreSignedResponse,
+) => {
+ await axios.put(presigned.upload_url, file, {
+ headers: {
+ ...presigned.signed_headers,
+ "Content-Type": file.type,
+ },
+ });
+};
+
+export const confirmUpload = async (token_id: string) => {
+ const res = await api.post("/media/presigned/complete", {
+ token_id,
+ });
+
+ return res.data;
+};
+export const uploadMedia = async (file: File) => {
+ const { data: presigned } = await api.get(
+ "/media/presigned",
+ {
+ params: {
+ fileName: file.name,
+ contentType: file.type,
+ size: file.size,
+ },
+ },
+ );
+
+ await uploadFileToS3(file, presigned);
+
+ const media = await confirmUpload(presigned.token_id);
+
+ return media;
+};