implemented upload of asset list as csv to s3

This commit is contained in:
Khalim Conn-Kowlessar 2024-11-20 16:34:31 +00:00
parent 325387b743
commit eaa9d82384

View file

@ -8,6 +8,8 @@ import { Float } from "@headlessui-float/react";
import { ChevronDownIcon } from "@heroicons/react/20/solid";
import { useMutation } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { add } from "cypress/types/lodash";
import { post } from "cypress/types/jquery";
type Option = {
label: string;
@ -113,6 +115,32 @@ export function SelectDropdown({
);
}
async function uploadCsvToS3({
presignedUrl,
file,
}: {
presignedUrl: string;
file: Blob;
}) {
try {
const response = await fetch(presignedUrl, {
method: "PUT",
body: file,
headers: { "Content-Type": "text/csv" },
});
if (!response.ok) {
console.error(response);
throw new Error("Network response was not ok");
}
} catch (error) {
console.error(error);
throw new Error("Upload failed.");
}
return { success: true };
}
async function generatePresignedUrl({
userId,
portfolioId,
@ -146,7 +174,32 @@ function generateS3Keys(userId: string, portfolioId: string) {
return { assetListFileKey, valuationDataFileKey };
}
function useCreateRemoteAssessment({ portfolioId }: { portfolioId: string }) {
type GenericObject = Record<string, any>;
const convertToCSV = <T extends GenericObject>(data: T[]): string => {
// Get headers (keys from the first object)
const headers = Object.keys(data[0]) as (keyof T)[];
// Create CSV rows
const rows = data.map((row) =>
headers.map((header) => row[header]).join(",")
);
// Combine headers and rows into CSV string
return [headers.join(","), ...rows].join("\n");
};
function useCreateRemoteAssessment({
portfolioId,
uprn,
addressLineOne,
postcode,
}: {
portfolioId: string;
uprn: number | null;
addressLineOne: string;
postcode: string;
}) {
// 1) We want to upload the asset data. To do this, we format the asset data, generate a presigned URL, and upload the data to S3.
// 2) We then want to upload valuation data. To do this, we format the valuation data, generate a presigned URL, and upload the data to S3.
// 3) Trigger the engine!!!! This is an api at /api/plan/trigger with our body that we looked at in Miro
@ -161,6 +214,25 @@ function useCreateRemoteAssessment({ portfolioId }: { portfolioId: string }) {
[userId, portfolioId]
);
const {
mutate: mutateUploadAssetList,
isLoading: uploadAssetListIsLoading,
isError: uploadAssetListIsError,
} = useMutation(uploadCsvToS3, {
onSuccess: (data) => {
console.log("WAS IT A SUCCESS?", data.success);
console.log("TRIGGERING THE ENGINE");
// This is where we trigger the engine!!!
const body = {
trigger_file_path: assetListFileKey,
};
// engine API call goes here
},
onError: (error) => {
console.error(error);
},
});
const {
mutate: mutatePresignedUrl,
isLoading: presignedUrlIsLoading,
@ -169,6 +241,19 @@ function useCreateRemoteAssessment({ portfolioId }: { portfolioId: string }) {
onSuccess: (data) => {
console.log(data.url);
// On success, upload to that URL!!!!
const assetList = [
{
uprn: uprn,
address: addressLineOne,
postcode: postcode,
},
];
const assetListCsvString = convertToCSV(assetList);
const assetListCsv = new Blob([assetListCsvString], {
type: "text/csv",
});
mutateUploadAssetList({ presignedUrl: data.url, file: assetListCsv });
},
onError: (error) => {
console.error(error);
@ -202,7 +287,7 @@ export default function RemoteAssesmentModal({
const [goalValue, setGoalValue] = useState<string>("");
const [addressLineOne, setAddressLineOne] = useState<string>("");
const [postcode, setPostcode] = useState<string>("");
const [uprn, setUprn] = useState<number | string | null>("");
const [uprn, setUprn] = useState<number | null>(null);
const [valuation, setValuation] = useState<number | string | null>("");
const [buttonDisabled, setButtonDisabled] = useState(true);
@ -221,7 +306,7 @@ export default function RemoteAssesmentModal({
}
function handleUprnChange(event: React.ChangeEvent<HTMLInputElement>) {
setUprn(event.target.value);
setUprn(Number(event.target.value));
}
function handleValuationChange(event: React.ChangeEvent<HTMLInputElement>) {
@ -231,6 +316,9 @@ export default function RemoteAssesmentModal({
const { handleSubmit, presignedUrlIsLoading, presignedUrlIsError } =
useCreateRemoteAssessment({
portfolioId,
uprn,
addressLineOne,
postcode,
});
useEffect(() => {