diff --git a/src/app/api/upload/csv/route.ts b/src/app/api/upload/csv/route.ts
index f26e918..faf865d 100644
--- a/src/app/api/upload/csv/route.ts
+++ b/src/app/api/upload/csv/route.ts
@@ -13,7 +13,7 @@ function generateS3Key(userId: number, portfolioId: number, filename: string) {
return key;
}
-export async function GET(request: NextRequest) {
+export async function POST(request: NextRequest) {
// For the moment, this api specifically handles uploads of csvs
const body = await request.json();
diff --git a/src/app/components/portfolio/Toolbar.tsx b/src/app/components/portfolio/Toolbar.tsx
index 3ff9fdf..e3f747f 100644
--- a/src/app/components/portfolio/Toolbar.tsx
+++ b/src/app/components/portfolio/Toolbar.tsx
@@ -55,7 +55,11 @@ export function Toolbar({ portfolioId }: ToolbarProps) {
setIsUploadCsvOpen={setModalIsOpen}
/>
-
+
);
}
diff --git a/src/app/components/portfolio/UploadCsvModal.tsx b/src/app/components/portfolio/UploadCsvModal.tsx
index d91d8d8..2a619e4 100644
--- a/src/app/components/portfolio/UploadCsvModal.tsx
+++ b/src/app/components/portfolio/UploadCsvModal.tsx
@@ -9,63 +9,119 @@ import { Input } from "@/app/shadcn_components/ui/input";
import { Label } from "@/app/shadcn_components/ui/label";
import { useRouter } from "next/navigation";
import { useMutation } from "@tanstack/react-query";
-import Link from "next/link";
+import { useSession } from "next-auth/react";
+
+async function generatePresignedUrl({
+ userId,
+ portfolioId,
+}: {
+ userId: number;
+ portfolioId: number;
+}) {
+ const body = JSON.stringify({ userId: userId, portfolioId: portfolioId });
+ console.log("body before: ", body);
+
+ const presignedResponse = await fetch(`/api/upload/csv`, {
+ method: "POST",
+ body: body,
+ });
+ if (!presignedResponse.ok) {
+ throw new Error("Network response was not ok");
+ }
+ const presignedUrl = await presignedResponse.json();
+ return presignedUrl;
+}
+
+async function uploadCsvToS3({
+ presignedUrl,
+ file,
+}: {
+ presignedUrl: string;
+ file: File;
+}) {
+ console.log("Uploading file to s3");
+ const upload = await fetch(presignedUrl, {
+ method: "PUT",
+ body: file,
+ });
+
+ if (!upload.ok) {
+ throw new Error("Upload failed.");
+ }
+
+ return upload;
+}
export const SubmitPlan = ({
buttonDisabled,
goal,
housingType,
goalValue,
+ file,
+ portfolioId,
}: {
buttonDisabled: boolean;
goal: string;
housingType: string;
goalValue: string;
+ file: File | null;
+ portfolioId: number;
}) => {
const router = useRouter();
+ const session = useSession();
+ // This state will hold the presignedUrl once it is available
+ const [presignedUrl, setPresignedUrl] = useState(null);
- async function triggerPlanBuild() {
- const requestBody = JSON.stringify({
- goal: goal,
- goalValue: goalValue,
- housingType: housingType,
- });
-
- const response = await fetch("/api/portfolio/plan", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
+ const { mutate: mutateUploadCsv, isLoading: isUploadLoading } = useMutation(
+ uploadCsvToS3,
+ {
+ onSuccess: (data) => {
+ return data;
+ },
+ onError: (error) => {
+ // handle error
+ console.error(error);
},
- body: requestBody,
- });
-
- if (!response.ok) {
- throw new Error("Network response was not ok");
}
+ );
- return response.json();
- }
-
- const { mutate, isLoading } = useMutation(triggerPlanBuild, {
+ const { mutate, isLoading } = useMutation(generatePresignedUrl, {
onSuccess: (data) => {
- console.log("uploading csv");
- // router.push(`/portfolio/${data.id}`);
+ // After the presigned URL has been generated, we can upload the file to S3
+ mutateUploadCsv({ presignedUrl: data.url, file: file });
},
onError: (error) => {
// handle error
- console.log(error);
+ console.error(error);
},
});
- const handleSubmit = () => {
- mutate();
+ if (!session.data) {
+ // The user is not logged in, redirect them to sign in
+ router.push("/");
+ return null;
+ }
+ const userId = session.data.user.dbId;
+
+ const handlePlanBuild = () => {
+ // The plan build is triggered by clicking submit which will:
+ // 1) Generate a pre-signed url to upload to
+ // 2) Upload the csv to the pre-signed url
+ // 3) Trigger the job to build the plan
+ // 4) Redirect the user to some loading page - this could be the portfolio page itself and we just trigger a regresh with skeleton cards for the properties
+ mutate({ userId: userId, portfolioId: portfolioId });
+
+ // mutateUploadCsv(presignedUrl);
+
+ // console.log("Redirect user to loading page");
+ // router.push("/portfolio/somewhere");
};
return (