mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
Refactor Apply page component to use DualOptionSelector component for handling yes/no choices
This commit is contained in:
parent
55b8d8759b
commit
a3573c5c9a
@ -24,16 +24,23 @@ import {
|
|||||||
} from "@/components/ui/tooltip";
|
} from "@/components/ui/tooltip";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { Selector } from "@/components/selector";
|
import { DualOptionSelector } from "@/components/dualSelector";
|
||||||
|
import { MultipleOptionSelector } from "@/components/multipleSelector";
|
||||||
|
|
||||||
export default function Apply() {
|
export default function Apply() {
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
companyName: z.string().min(5, {
|
companyName: z.string().min(5, {
|
||||||
message: "Company name must be at least 5 characters.",
|
message: "Company name must be at least 5 characters.",
|
||||||
}),
|
}),
|
||||||
totalRaised: z.number().int({
|
industry: z.string(),
|
||||||
message: "Total raised must be an integer.",
|
isInUS: z.string(),
|
||||||
}),
|
totalRaised: z
|
||||||
|
.number({
|
||||||
|
required_error: "Total raised must be a number.",
|
||||||
|
invalid_type_error: "Total raised must be a valid number.",
|
||||||
|
})
|
||||||
|
.positive()
|
||||||
|
.max(9999999999, "Total raised must be a realistic amount."),
|
||||||
});
|
});
|
||||||
let supabase = createSupabaseClient();
|
let supabase = createSupabaseClient();
|
||||||
const {
|
const {
|
||||||
@ -45,7 +52,6 @@ export default function Apply() {
|
|||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
});
|
});
|
||||||
const [industry, setIndustry] = useState<string[]>([]);
|
const [industry, setIndustry] = useState<string[]>([]);
|
||||||
const [selectedIndustry, setSelectedIndustry] = useState("");
|
|
||||||
const [isInUS, setIsInUS] = useState("");
|
const [isInUS, setIsInUS] = useState("");
|
||||||
const [isForSale, setIsForSale] = useState("");
|
const [isForSale, setIsForSale] = useState("");
|
||||||
const [isGenerating, setIsGenerating] = useState("");
|
const [isGenerating, setIsGenerating] = useState("");
|
||||||
@ -65,6 +71,13 @@ export default function Apply() {
|
|||||||
"100K+",
|
"100K+",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
register("industry");
|
||||||
|
register("isInUS");
|
||||||
|
register("isForSale");
|
||||||
|
register("isGenerating");
|
||||||
|
}, [register]);
|
||||||
|
|
||||||
const handleRemoveImage = (index: number) => {
|
const handleRemoveImage = (index: number) => {
|
||||||
const updatedImages = selectedImages.filter((_, i) => i !== index);
|
const updatedImages = selectedImages.filter((_, i) => i !== index);
|
||||||
setSelectedImages(updatedImages);
|
setSelectedImages(updatedImages);
|
||||||
@ -79,11 +92,8 @@ export default function Apply() {
|
|||||||
const onSubmit = (data: any) => {
|
const onSubmit = (data: any) => {
|
||||||
console.table(data);
|
console.table(data);
|
||||||
};
|
};
|
||||||
const handleFieldChange = (fieldName: string, value: string) => {
|
const handleFieldChange = (fieldName: string, value: any) => {
|
||||||
switch (fieldName) {
|
switch (fieldName) {
|
||||||
case "industry":
|
|
||||||
setSelectedIndustry(value);
|
|
||||||
break;
|
|
||||||
case "isInUS":
|
case "isInUS":
|
||||||
setIsInUS(value);
|
setIsInUS(value);
|
||||||
break;
|
break;
|
||||||
@ -147,7 +157,7 @@ export default function Apply() {
|
|||||||
</div>
|
</div>
|
||||||
{/* form */}
|
{/* form */}
|
||||||
<form action="" onSubmit={handleSubmit(onSubmit)}>
|
<form action="" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="grid grid-flow-row auto-rows-max w-3/4 ml-48">
|
<div className="grid grid-flow-row auto-rows-max w-3/4 ml-1/2">
|
||||||
<h1 className="text-3xl font-bold mt-10 ml-96">About your company</h1>
|
<h1 className="text-3xl font-bold mt-10 ml-96">About your company</h1>
|
||||||
<p className="ml-96 mt-5 text-neutral-500">
|
<p className="ml-96 mt-5 text-neutral-500">
|
||||||
All requested information in this section is required.
|
All requested information in this section is required.
|
||||||
@ -182,41 +192,24 @@ export default function Apply() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* industry */}
|
{/* industry */}
|
||||||
<div className="mt-10 space-y-5">
|
|
||||||
<Label htmlFor="industry" className="font-bold text-lg mt-10">
|
<MultipleOptionSelector
|
||||||
Industry
|
header={<>Industry</>}
|
||||||
</Label>
|
fieldName="industry"
|
||||||
<div className="flex space-x-5">
|
choices={industry}
|
||||||
<Select
|
handleFunction={handleFieldChange}
|
||||||
onValueChange={(value) =>
|
description={
|
||||||
handleFieldChange("industry", value)
|
<>Choose the industry that best aligns with your business.</>
|
||||||
}
|
}
|
||||||
>
|
placeholder="Select an industry"
|
||||||
<SelectTrigger className="w-96">
|
selectLabel="Industry"
|
||||||
<SelectValue placeholder="Select an industry" />
|
/>
|
||||||
</SelectTrigger>
|
{/* <input
|
||||||
<SelectContent>
|
type="hidden"
|
||||||
<SelectGroup>
|
{...register("industry")}
|
||||||
<SelectLabel>Industry</SelectLabel>
|
value={selectedIndustry}
|
||||||
{industry.map((i) => (
|
/> */}
|
||||||
<SelectItem key={i} value={i}>
|
{/* {selectedIndustry} */}
|
||||||
{i}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectGroup>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<input
|
|
||||||
type="hidden"
|
|
||||||
{...register("industry")}
|
|
||||||
value={selectedIndustry}
|
|
||||||
/>
|
|
||||||
{/* {selectedIndustry} */}
|
|
||||||
<span className="text-[12px] text-neutral-500 self-center">
|
|
||||||
Choose the industry that best aligns with your business.
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* How much money has your company raised to date? */}
|
{/* How much money has your company raised to date? */}
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<Label htmlFor="totalRaised" className="font-bold text-lg">
|
<Label htmlFor="totalRaised" className="font-bold text-lg">
|
||||||
@ -224,11 +217,13 @@ export default function Apply() {
|
|||||||
</Label>
|
</Label>
|
||||||
<div className="flex space-x-5">
|
<div className="flex space-x-5">
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="number"
|
||||||
id="totalRaised"
|
id="totalRaised"
|
||||||
className="w-96"
|
className="w-96"
|
||||||
placeholder="$ 1,000,000"
|
placeholder="$ 1,000,000"
|
||||||
{...register("totalRaised")}
|
{...register("totalRaised", {
|
||||||
|
valueAsNumber: true,
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
<span className="text-[12px] text-neutral-500 self-center">
|
<span className="text-[12px] text-neutral-500 self-center">
|
||||||
The sum total of past financing, including angel or venture{" "}
|
The sum total of past financing, including angel or venture{" "}
|
||||||
@ -236,9 +231,18 @@ export default function Apply() {
|
|||||||
capital, loans, grants, or token sales.
|
capital, loans, grants, or token sales.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
{errors.totalRaised && (
|
||||||
|
<p className="text-red-500 text-sm">
|
||||||
|
{errors.totalRaised && (
|
||||||
|
<p className="text-red-500 text-sm">
|
||||||
|
{errors.totalRaised.message as string}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* Is your company incorporated in the United States? */}
|
{/* Is your company incorporated in the United States? */}
|
||||||
<Selector
|
<DualOptionSelector
|
||||||
label={
|
label={
|
||||||
<>
|
<>
|
||||||
Is your company incorporated in the <br />
|
Is your company incorporated in the <br />
|
||||||
@ -262,7 +266,7 @@ export default function Apply() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Is your product available (for sale) in market? */}
|
{/* Is your product available (for sale) in market? */}
|
||||||
<Selector
|
<DualOptionSelector
|
||||||
label={
|
label={
|
||||||
<>
|
<>
|
||||||
Is your product available (for sale) <br />
|
Is your product available (for sale) <br />
|
||||||
@ -284,7 +288,7 @@ export default function Apply() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Is your company generating revenue?*/}
|
{/* Is your company generating revenue?*/}
|
||||||
<Selector
|
<DualOptionSelector
|
||||||
label={<>Is your company generating revenue?</>}
|
label={<>Is your company generating revenue?</>}
|
||||||
name="isGenerating"
|
name="isGenerating"
|
||||||
choice1="Yes"
|
choice1="Yes"
|
||||||
@ -367,10 +371,11 @@ export default function Apply() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex space-x-5">
|
<div className="flex space-x-5">
|
||||||
<Switch onCheckedChange={() => setApplyProject(!applyProject)}>
|
<Switch
|
||||||
Apply your first project!
|
onCheckedChange={() => setApplyProject(!applyProject)}
|
||||||
</Switch>
|
></Switch>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
@ -396,7 +401,7 @@ export default function Apply() {
|
|||||||
{applyProject && (
|
{applyProject && (
|
||||||
<div className="grid auto-rows-max w-3/4 ml-48 bg-zinc-100 dark:bg-zinc-900 mt-10 pt-12 pb-12">
|
<div className="grid auto-rows-max w-3/4 ml-48 bg-zinc-100 dark:bg-zinc-900 mt-10 pt-12 pb-12">
|
||||||
{/* header */}
|
{/* header */}
|
||||||
<div className="ml-96">
|
<div className="ml-[15%]">
|
||||||
<h1 className="text-3xl font-bold mt-10">
|
<h1 className="text-3xl font-bold mt-10">
|
||||||
Begin Your First Fundraising Project
|
Begin Your First Fundraising Project
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ interface SelectorInterface {
|
|||||||
description: ReactElement;
|
description: ReactElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Selector(props: SelectorInterface) {
|
export function DualOptionSelector(props: SelectorInterface) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<Label htmlFor={props.name} className="font-bold text-lg">
|
<Label htmlFor={props.name} className="font-bold text-lg">
|
||||||
56
src/components/multipleSelector.tsx
Normal file
56
src/components/multipleSelector.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectLabel,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
|
||||||
|
interface MultipleOptionSelector {
|
||||||
|
header: ReactElement;
|
||||||
|
fieldName: string;
|
||||||
|
choices: string[];
|
||||||
|
handleFunction: Function;
|
||||||
|
description: ReactElement;
|
||||||
|
placeholder: string;
|
||||||
|
selectLabel: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MultipleOptionSelector(props: MultipleOptionSelector) {
|
||||||
|
return (
|
||||||
|
<div className="mt-10 space-y-5">
|
||||||
|
<Label htmlFor={props.fieldName} className="font-bold text-lg mt-10">
|
||||||
|
{props.header}
|
||||||
|
</Label>
|
||||||
|
<div className="flex space-x-5">
|
||||||
|
<Select
|
||||||
|
onValueChange={(value) => {
|
||||||
|
props.handleFunction(props.fieldName, value);
|
||||||
|
// console.log(value, props.fieldName);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="w-96">
|
||||||
|
<SelectValue placeholder={props.placeholder} />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectLabel>{props.selectLabel}</SelectLabel>
|
||||||
|
{props.choices.map((i) => (
|
||||||
|
<SelectItem key={i} value={i}>
|
||||||
|
{i}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<span className="text-[12px] text-neutral-500 self-center">
|
||||||
|
{props.description}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user