diff --git a/src/app/api/generalApi.ts b/src/app/api/generalApi.ts index a214c8b..aa7c50b 100644 --- a/src/app/api/generalApi.ts +++ b/src/app/api/generalApi.ts @@ -1,48 +1,91 @@ import { createSupabaseClient } from "@/lib/supabase/clientComponentClient"; import Swal from "sweetalert2"; +const supabase = createSupabaseClient(); + +async function checkFolderExists(bucketName: string, filePath: string) { + const { data, error } = await supabase.storage + .from(bucketName) + .list(filePath); + + if (error) { + console.error(`Error checking for folder: ${error.message}`); + } + return { folderData: data, folderError: error }; +} + +async function clearFolder( + bucketName: string, + folderData: any[], + filePath: string +) { + const errors: string[] = []; + + for (const fileItem of folderData) { + const { error } = await supabase.storage + .from(bucketName) + .remove([`${filePath}/${fileItem.name}`]); + + if (error) { + errors.push(`Error removing file (${fileItem.name}): ${error.message}`); + } + } + + return errors; +} + +async function uploadToFolder( + bucketName: string, + filePath: string, + file: File +) { + const { data, error } = await supabase.storage + .from(bucketName) + .upload(filePath, file, { upsert: true }); + + if (error) { + console.error(`Error uploading file: ${error.message}`); + } + return { uploadData: data, uploadError: error }; +} + export async function uploadFile( file: File, bucketName: string, filePath: string ) { - const supabase = createSupabaseClient(); - let errorMessages: string[] = []; + const errorMessages: string[] = []; // check if the folder exists - const { data: folderData, error: folderError } = await supabase.storage - .from(bucketName) - .list(filePath); - + const { folderData, folderError } = await checkFolderExists( + bucketName, + filePath + ); if (folderError) { errorMessages.push(`Error checking for folder: ${folderError.message}`); } - // if the folder exists, clear the folder + // clear the folder if it exists if (folderData && folderData.length > 0) { - for (const fileItem of folderData) { - const { error: removeError } = await supabase.storage - .from(bucketName) - .remove([`${filePath}/${fileItem.name}`]); - - if (removeError) { - errorMessages.push( - `Error removing file (${fileItem.name}): ${removeError.message}` - ); - } - } + const clearErrors = await clearFolder(bucketName, folderData, filePath); + errorMessages.push(...clearErrors); } - // upload the new file to the folder (if no folderError) + // upload the new file if there were no previous errors + let uploadData = null; if (errorMessages.length === 0) { - const { error: uploadError } = await supabase.storage - .from(bucketName) - .upload(filePath, file); + const { uploadData: data, uploadError } = await uploadToFolder( + bucketName, + filePath, + file + ); + uploadData = data; if (uploadError) { errorMessages.push(`Error uploading file: ${uploadError.message}`); } } + if (errorMessages.length > 0) { Swal.fire({ icon: "error", @@ -50,7 +93,8 @@ export async function uploadFile( html: errorMessages.join("
"), confirmButtonColor: "red", }); - return false; + return { success: false, errors: errorMessages, data: null }; } - return true; + + return { success: true, errors: null, data: uploadData }; } diff --git a/src/app/project/apply/page.tsx b/src/app/project/apply/page.tsx index e88a65a..489953a 100644 --- a/src/app/project/apply/page.tsx +++ b/src/app/project/apply/page.tsx @@ -15,7 +15,7 @@ export default function ApplyProject() { const onSubmit: SubmitHandler = async (data) => { alert("มาแน้ววว"); await sendApplication(data); - console.table(data); + // console.table(data); // console.log(typeof data["projectPhotos"], data["projectPhotos"]); }; const saveApplicationData = async (recvData: any, userId: string) => { @@ -41,15 +41,19 @@ export default function ApplyProject() { }; const saveTags = async (tags: string[], projectId: string) => { const tagPromises = tags.map(async (tag) => { - const { data, error } = await supabase + const response = await supabase .from("project_application_tag") - .insert([{ tag_id: tag, project_id: projectId }]) + .insert([{ tag_id: tag, item_id: projectId }]) .select(); - return { data, error }; + // console.log("Insert response for tag:", tag, response); + + return response; }); const results = await Promise.all(tagPromises); + + // Collect errors const errors = results .filter((result) => result.error) .map((result) => result.error); @@ -69,7 +73,7 @@ export default function ApplyProject() { return await uploadFile( file, - "BUCKET_PITCH_APPLICATION_NAME", + BUCKET_PITCH_APPLICATION_NAME, `${userId}/${projectId}/pitches/${file.name}` ); }; @@ -80,29 +84,44 @@ export default function ApplyProject() { userId: string, projectId: string ) => { + const uploadResults: { logo?: any; photos: any[] } = { photos: [] }; + + // upload logo if (logoFile) { - const uploadLogoSuccess = await uploadFile( + const logoResult = await uploadFile( logoFile, - "BUCKET_PITCH_APPLICATION_NAME", + BUCKET_PITCH_APPLICATION_NAME, `${userId}/${projectId}/logo/${logoFile.name}` ); - if (!uploadLogoSuccess) { - console.error("Error uploading logo."); - return false; + if (!logoResult.success) { + console.error("Error uploading logo:", logoResult.errors); + return { success: false, logo: logoResult, photos: [] }; } + + uploadResults.logo = logoResult; } + // upload each photo const uploadPhotoPromises = photos.map((image) => uploadFile( image, - "BUCKET_PITCH_APPLICATION_NAME", + BUCKET_PITCH_APPLICATION_NAME, `${userId}/${projectId}/photos/${image.name}` ) ); const photoResults = await Promise.all(uploadPhotoPromises); - return photoResults.every(Boolean); // Checks if all photos uploaded successfully + uploadResults.photos = photoResults; + + // check if all uploads were successful + const allUploadsSuccessful = photoResults.every((result) => result.success); + + return { + success: allUploadsSuccessful, + logo: uploadResults.logo, + photos: uploadResults.photos, + }; }; const displayAlert = (error: any) => { @@ -114,7 +133,7 @@ export default function ApplyProject() { confirmButtonColor: error == null ? "green" : "red", }).then((result) => { if (result.isConfirmed) { - window.location.href = "/"; + // window.location.href = "/"; } }); }; @@ -136,6 +155,11 @@ export default function ApplyProject() { displayAlert(error); return; } + const tagError = saveTags(recvData["tag"], projectId); + // if (tagError) { + // displayAlert(tagError); + // return; + // } // upload pitch file if it’s a file if (typeof recvData["projectPitchDeck"] === "object") { @@ -153,18 +177,48 @@ export default function ApplyProject() { } // upload logo and photos - const uploadMediaSuccess = await uploadLogoAndPhotos( + const { success, logo, photos } = await uploadLogoAndPhotos( recvData["projectLogo"], recvData["projectPhotos"], user.id, projectId ); - - if (!uploadMediaSuccess) { + if (!success) { console.error("Error uploading media files."); } + const folderPath = photos[0].data.path; + const lastSlashIndex = folderPath.lastIndexOf("/"); + const photosPath = folderPath.substring(0, lastSlashIndex); + const logoURL = getPublicURL( + logo.data.path, + BUCKET_PITCH_APPLICATION_NAME + )?.publicUrl; + const photosURL = getPublicURL( + photosPath, + BUCKET_PITCH_APPLICATION_NAME + )?.publicUrl; + + updateImageURL(logoURL, "project_logo", projectId); + // console.log(logoURL, photosUrl); displayAlert(error); }; + const updateImageURL = async ( + url: string, + columnName: string, + projectId: number + ) => { + const { data, error } = await supabase + .from("project_application") + .update({ [columnName]: url }) + .eq("id", projectId) + .select(); + console.table(data); + }; + const getPublicURL = (path: string, bucketName: string) => { + const { data } = supabase.storage.from(bucketName).getPublicUrl(path); + // console.table(data); + return data; + }; return (