From ec17305e16239975390e439a08e902aa34b5fee5 Mon Sep 17 00:00:00 2001
From: THIS ONE IS A LITTLE BIT TRICKY KRUB
Date: Mon, 14 Oct 2024 17:46:40 +0700
Subject: [PATCH] Refactor Apply page component to adjust left margin for
company information section and simplify pitchDeckSchema validation
---
src/app/business/apply/page.tsx | 182 +++++++++++++++++++++-----------
1 file changed, 118 insertions(+), 64 deletions(-)
diff --git a/src/app/business/apply/page.tsx b/src/app/business/apply/page.tsx
index 3faf2f2..d39381c 100644
--- a/src/app/business/apply/page.tsx
+++ b/src/app/business/apply/page.tsx
@@ -19,12 +19,59 @@ import { DualOptionSelector } from "@/components/dualSelector";
import { MultipleOptionSelector } from "@/components/multipleSelector";
export default function Apply() {
+ const [industry, setIndustry] = useState([]);
+ const [isInUS, setIsInUS] = useState("");
+ const [isForSale, setIsForSale] = useState("");
+ const [isGenerating, setIsGenerating] = useState("");
+ const [businessPitch, setBusinessPitch] = useState("text");
+ const [projectType, setProjectType] = useState([]);
+ const [projectPitch, setProjectPitch] = useState("text");
+ const [applyProject, setApplyProject] = useState(false);
+ const [selectedImages, setSelectedImages] = useState([]);
+ const [businessPitchFile, setBusinessPitchFile] = useState("");
const MAX_FILE_SIZE = 5000000;
const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png"];
- const pitchDeckSchema = z.union([
- z.string().url("Pitch deck must be a valid URL."),
- z.object({}),
- ]);
+ const createPitchDeckSchema = (inputType: string) => {
+ if (inputType === "text") {
+ return z
+ .string()
+ .url("Pitch deck must be a valid URL.")
+ .refine((url) => url.endsWith(".md"), {
+ message: "Pitch deck URL must link to a markdown file (.md).",
+ });
+ } else if (inputType === "file") {
+ return z
+ .custom(
+ (val) => {
+ // Confirm val is a File object
+ return val instanceof File; // Ensure it is a File instance
+ },
+ {
+ message: "Input must be a file.",
+ }
+ )
+ .refine((file) => file.size < MAX_FILE_SIZE, {
+ message: "File can't be bigger than 5MB.",
+ })
+ .refine((file) => file.name.endsWith(".md"), {
+ message: "File must be a markdown file (.md).",
+ });
+ } else {
+ return z.any(); // avoid undefined
+ }
+ };
+ const projectLogoSchema = z
+ .custom(
+ (val) => val && typeof val === "object" && "size" in val && "type" in val,
+ { message: "Input must be a file." }
+ )
+ .refine((file) => file.size < MAX_FILE_SIZE, {
+ message: "File can't be bigger than 5MB.",
+ })
+ .refine((file) => ACCEPTED_IMAGE_TYPES.includes(file.type), {
+ message: "File format must be either jpg, jpeg, or png.",
+ });
+
const projectFormSchema = z.object({
projectName: z.string().min(5, {
message: "Project name must be at least 5 characters.",
@@ -39,33 +86,26 @@ export default function Apply() {
.min(10, {
message: "Short description must be at least 10 characters.",
}),
- projectPitchDeck: pitchDeckSchema,
- projectLogo: z
- .instanceof(File)
- .refine((file) => ACCEPTED_IMAGE_TYPES.includes(file.type), {
- message: "Only .jpg, .jpeg, and .png formats are supported.",
- })
- .refine((file) => file.size <= MAX_FILE_SIZE, {
- message: "Max image size is 5MB.",
- }),
+ projectPitchDeck: createPitchDeckSchema(projectPitch),
+ projectLogo: projectLogoSchema,
- projectPhotos: z
- .array(
- z.object({
- file: z
- .any()
- .refine(
- (file) => file?.size <= MAX_FILE_SIZE,
- `Max image size is 5MB.`
- )
- .refine(
- (file) => ACCEPTED_IMAGE_TYPES.includes(file?.type),
- "Only .jpg, .jpeg, and .png formats are supported."
- ),
- })
- )
- .min(1, "You must upload at least one photo.")
- .max(10, "You can upload a maximum of 10 photos."),
+ // projectPhotos: z
+ // .array(
+ // z.object({
+ // file: z
+ // .any()
+ // .refine(
+ // (file) => file?.size <= MAX_FILE_SIZE,
+ // `Max image size is 5MB.`
+ // )
+ // .refine(
+ // (file) => ACCEPTED_IMAGE_TYPES.includes(file?.type),
+ // "Only .jpg, .jpeg, and .png formats are supported."
+ // ),
+ // })
+ // )
+ // .min(1, "You must upload at least one photo.")
+ // .max(10, "You can upload a maximum of 10 photos."),
minInvest: z
.number({
required_error: "Minimum invesment must be a number.",
@@ -132,23 +172,12 @@ export default function Apply() {
communitySize: z.string({
required_error: "Please select one of the option",
}),
- businessPitchDeck: pitchDeckSchema,
+ businessPitchDeck: createPitchDeckSchema(businessPitch),
});
let supabase = createSupabaseClient();
-
- const [industry, setIndustry] = useState([]);
- const [isInUS, setIsInUS] = useState("");
- const [isForSale, setIsForSale] = useState("");
- const [isGenerating, setIsGenerating] = useState("");
- const [businessPitch, setBusinessPitch] = useState("");
- const [projectType, setProjectType] = useState([]);
- const [projectPitch, setProjectPitch] = useState("");
- const [applyProject, setApplyProject] = useState(false);
- const [selectedImages, setSelectedImages] = useState([]);
const {
register,
handleSubmit,
- setValue,
setValue: setValueBusiness,
formState: { errors: errorsBusiness },
} = useForm({
@@ -243,7 +272,7 @@ export default function Apply() {
const fetchIndustry = async () => {
let { data: BusinessType, error } = await supabase
- .from("BusinessType")
+ .from("business_type")
.select("value");
if (error) {
@@ -257,6 +286,9 @@ export default function Apply() {
};
const onSubmitSingleForm = (data: any) => {
+ const pitchDeckSchema = createPitchDeckSchema(businessPitch); // Ensure you create the schema dynamically
+ pitchDeckSchema.parse(data.businessPitchDeck); // Validate the specific field
+ console.log("Valid form input:", data);
alert(JSON.stringify(data));
};
@@ -278,7 +310,7 @@ export default function Apply() {
};
const fetchProjectType = async () => {
let { data: ProjectType, error } = await supabase
- .from("ProjectType")
+ .from("project_type")
.select("value");
if (error) {
@@ -503,9 +535,16 @@ export default function Apply() {
: "https:// "
}
accept={businessPitch === "file" ? ".md" : undefined}
- {...register("businessPitchDeck", { required: true })}
+ {...(businessPitch === "text"
+ ? register("businessPitchDeck", { required: true })
+ : {
+ onChange: (e) => {
+ const file = e.target.files?.[0];
+ setValueBusiness("businessPitchDeck", file);
+ setBusinessPitchFile(file?.name || "");
+ },
+ })}
/>
-
Your pitch deck and other application info will be used for{" "}
@@ -519,10 +558,25 @@ export default function Apply() {
+ {/* box to show file name */}
+ {businessPitchFile && (
+
+ 1. {businessPitchFile}
+
+
+ )}
- {errorsBusiness.pitchDeck && (
+ {errorsBusiness.businessPitchDeck && (
- {errorsBusiness.pitchDeck.message as string}
+ {errorsBusiness.businessPitchDeck.message as string}
)}
-
{/* project's name */}