fix: fix fail send project application and ui loader not removed

This commit is contained in:
Sosokker 2024-11-09 15:50:48 +07:00
parent 5c455d20ee
commit 6c486d9dd7
2 changed files with 98 additions and 140 deletions

View File

@ -1,4 +1,6 @@
import { useEffect, useState } from "react";
"use client";
import React, { useEffect, useState } from "react";
import { SubmitHandler, useForm, ControllerRenderProps } from "react-hook-form";
import { Button } from "@/components/ui/button";
import { MultipleOptionSelector } from "@/components/multipleSelector";
@ -9,7 +11,7 @@ import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { Label } from "@/components/ui/label";
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
import { Textarea } from "./ui/textarea";
import { Textarea } from "@/components/ui/textarea";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { cn } from "@/lib/utils";
@ -93,7 +95,9 @@ const ProjectForm = ({ onSubmit }: ProjectFormProps & { onSubmit: SubmitHandler<
useEffect(() => {
fetchProjectType();
fetchTag();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit as SubmitHandler<projectSchema>)} className="space-y-8">

View File

@ -1,29 +1,57 @@
"use client";
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
import ProjectForm from "@/components/ProjectForm";
import ProjectForm from "./ProjectForm";
import { projectFormSchema } from "@/types/schemas/application.schema";
import { z } from "zod";
import { SubmitHandler } from "react-hook-form";
import Swal from "sweetalert2";
import { uploadFile } from "@/app/api/generalApi";
import { Loader } from "@/components/loading/loader";
import { useState } from "react";
import { errors } from "@playwright/test";
import { useRouter } from "next/navigation";
import toast from "react-hot-toast";
import { useUserRole } from "@/hooks/useUserRole";
import { LegacyLoader } from "@/components/loading/LegacyLoader";
type projectSchema = z.infer<typeof projectFormSchema>;
let supabase = createSupabaseClient();
const supabase = createSupabaseClient();
const BUCKET_PITCH_APPLICATION_NAME = "project-application";
export default function ApplyProject() {
const [isSuccess, setIsSuccess] = useState(true);
const onSubmit: SubmitHandler<projectSchema> = async (data) => {
// alert("มาแน้ววว");
await sendApplication(data);
// console.table(data);
// console.log(typeof data["projectPhotos"], data["projectPhotos"]);
const router = useRouter();
const { data, session, isLoading, error } = useUserRole();
const userId = session?.user.id;
const role: string = data?.role;
if (isLoading || !session) {
return <LegacyLoader />;
}
if (error) {
throw error;
}
if (role != "business") {
router.push("/business/apply");
toast.error("Please apply to raise on B2DVentures first!");
return;
}
const displayAlert = (error: any) => {
Swal.fire({
icon: error == null ? "success" : "error",
title: error == null ? "Success" : `Error: ${error.code}`,
text: error == null ? "Your application has been submitted" : error.message,
confirmButtonColor: error == null ? "green" : "red",
allowOutsideClick: false,
}).then((result) => {
if (result.isConfirmed) {
toast.error("Error sending Project Application");
router.push("/");
}
});
};
const saveApplicationData = async (recvData: any, userId: string) => {
const saveApplicationData = async (recvData: any) => {
const pitchType = typeof recvData["projectPitchDeck"];
const { data: projectData, error: projectError } = await supabase
.from("project_application")
@ -43,183 +71,109 @@ export default function ApplyProject() {
return { projectId: projectData?.[0]?.id, error: projectError };
};
const saveTags = async (tags: string[], projectId: string) => {
const tagPromises = tags.map(async (tag) => {
const response = await supabase
.from("project_application_tag")
.insert([{ tag_id: tag, item_id: projectId }])
.select();
// 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);
return { errors };
};
const uploadPitchFile = async (file: File, userId: string, projectId: string) => {
if (!file || !userId) {
console.error("Pitch file or user ID is undefined.");
return false;
}
const uploadPitchFile = async (file: File, projectId: string) => {
if (!file || !userId) return false;
return await uploadFile(file, BUCKET_PITCH_APPLICATION_NAME, `${userId}/${projectId}/pitches/${file.name}`);
};
const uploadLogoAndPhotos = async (logoFile: File, photos: File[], userId: string, projectId: string) => {
const uploadLogoAndPhotos = async (logoFile: File, photos: File[], projectId: string) => {
const uploadResults: { logo?: any; photos: any[] } = { photos: [] };
// upload logo
if (logoFile) {
const logoResult = await uploadFile(
logoFile,
BUCKET_PITCH_APPLICATION_NAME,
`${userId}/${projectId}/logo/${logoFile.name}`
);
if (!logoResult.success) {
console.error("Error uploading logo:", logoResult.errors);
return { success: false, logo: logoResult, photos: [] };
}
if (!logoResult.success) return { success: false, logo: logoResult, photos: [] };
uploadResults.logo = logoResult;
}
// upload each photo
const uploadPhotoPromises = photos.map((image) =>
uploadFile(image, BUCKET_PITCH_APPLICATION_NAME, `${userId}/${projectId}/photos/${image.name}`)
);
const photoResults = await Promise.all(uploadPhotoPromises);
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,
};
return { success: allUploadsSuccessful, logo: uploadResults.logo, photos: uploadResults.photos };
};
const displayAlert = (error: any) => {
Swal.fire({
icon: error == null ? "success" : "error",
title: error == null ? "Success" : `Error: ${error.code}`,
text: error == null ? "Your application has been submitted" : error.message,
confirmButtonColor: error == null ? "green" : "red",
}).then((result) => {
if (result.isConfirmed) {
// window.location.href = "/";
}
});
};
const sendApplication = async (recvData: any) => {
setIsSuccess(false);
const {
data: { user },
} = await supabase.auth.getUser();
if (!user?.id) {
console.error("User ID is undefined.");
return;
}
// save application data
const { projectId, error } = await saveApplicationData(recvData, user.id);
if (error) {
displayAlert(error);
return;
}
const tagError = await saveTags(recvData["tag"], projectId);
// if (tagError) {
// displayAlert(tagError);
// return;
// }
// upload pitch file if its a file
if (typeof recvData["projectPitchDeck"] === "object") {
const uploadPitchSuccess = await uploadPitchFile(recvData["projectPitchDeck"], user.id, projectId);
if (!uploadPitchSuccess) {
console.error("Error uploading pitch file.");
} else {
console.log("Pitch file uploaded successfully.");
}
}
// upload logo and photos
const { success, logo, photos } = await uploadLogoAndPhotos(
recvData["projectLogo"],
recvData["projectPhotos"],
user.id,
projectId
);
if (!success) {
console.error("Error uploading media files.");
}
// console.log("Bucket Name:", BUCKET_PITCH_APPLICATION_NAME);
// console.log("Logo Path:", logo.data.path);
// console.table(photos);
const logoURL = await getPrivateURL(logo.data.path, BUCKET_PITCH_APPLICATION_NAME);
let photoURLsArray: string[] = [];
const photoURLPromises = photos.map(
async (item: { success: boolean; errors: typeof errors; data: { path: string } }) => {
const photoURL = await getPrivateURL(item.data.path, BUCKET_PITCH_APPLICATION_NAME);
if (photoURL?.signedUrl) {
photoURLsArray.push(photoURL.signedUrl);
} else {
console.error("Signed URL for photo is undefined.");
}
}
);
await Promise.all(photoURLPromises);
// console.log(logoURL.publicUrl, projectId, logo.data.path);
// console.log(logoURL?.signedUrl, projectId);
// console.log(photoURLsArray[0], photoURLsArray[1]);
if (logoURL?.signedUrl) {
await updateImageURL(logoURL.signedUrl, "project_logo", projectId);
} else {
console.error("Signed URL for logo is undefined.");
}
await updateImageURL(photoURLsArray, "project_photos", projectId);
// console.log(logoURL, photosUrl);
setIsSuccess(true);
displayAlert(error);
};
const updateImageURL = async (url: string | string[], columnName: string, projectId: number) => {
const { error } = await supabase
.from("project_application")
.update({ [columnName]: url })
.eq("id", projectId);
// console.log(
// `Updating ${columnName} with URL: ${url} for project ID: ${projectId}`
// );
if (error) {
console.error(error);
}
if (error) toast.error(error.message);
};
const getPrivateURL = async (path: string, bucketName: string) => {
const { data } = await supabase.storage.from(bucketName).createSignedUrl(path, 9999999999999999999999999999);
// console.table(data);
const { data } = await supabase.storage.from(bucketName).createSignedUrl(path, 31560000);
return data;
};
const sendApplication = async (recvData: any) => {
const { projectId, error } = await saveApplicationData(recvData);
if (error) {
displayAlert(error);
return;
}
await saveTags(recvData["tag"], projectId);
if (typeof recvData["projectPitchDeck"] === "object") {
await uploadPitchFile(recvData["projectPitchDeck"], projectId);
}
const { success, logo, photos } = await uploadLogoAndPhotos(
recvData["projectLogo"],
recvData["projectPhotos"],
projectId
);
if (!success) toast.error("Error uploading media files.");
const logoURL = await getPrivateURL(logo.data.path, BUCKET_PITCH_APPLICATION_NAME);
let photoURLsArray: string[] = [];
const photoURLPromises = photos.map(async (item) => {
const photoURL = await getPrivateURL(item.data.path, BUCKET_PITCH_APPLICATION_NAME);
if (photoURL?.signedUrl) photoURLsArray.push(photoURL.signedUrl);
});
await Promise.all(photoURLPromises);
if (logoURL?.signedUrl) await updateImageURL(logoURL.signedUrl, "project_logo", projectId);
await updateImageURL(photoURLsArray, "project_photos", projectId);
if (error) {
displayAlert(error);
router.push("/project/apply");
}
};
const onSubmit: SubmitHandler<projectSchema> = async (data) => {
await sendApplication(data);
};
return (
<div>
<Loader isSuccess={isSuccess} />
<div className="grid grid-flow-row auto-rows-max w-full h-52 md:h-92 bg-gray-2s00 dark:bg-gray-800 p-5">
<div className="grid grid-flow-row auto-rows-max w-full h-52 md:h-92 bg-gray-200 dark:bg-gray-800 p-5">
<h1 className="text-2xl md:text-5xl font-medium md:font-bold justify-self-center md:mt-8">
Apply to raise on B2DVentures
</h1>