Refactor ProjectForm component to add tag functionality

This commit is contained in:
THIS ONE IS A LITTLE BIT TRICKY KRUB 2024-10-20 18:25:28 +07:00
parent 40c45ed8d4
commit 2e1a58bbc8
2 changed files with 50 additions and 26 deletions

View File

@ -31,7 +31,7 @@ import {
PopoverTrigger, PopoverTrigger,
} from "@/components/ui/popover"; } from "@/components/ui/popover";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { ChevronsUpDown, Check } from "lucide-react"; import { ChevronsUpDown, Check, X } from "lucide-react";
type projectSchema = z.infer<typeof projectFormSchema>; type projectSchema = z.infer<typeof projectFormSchema>;
type FieldType = ControllerRenderProps<any, "projectPhotos">; type FieldType = ControllerRenderProps<any, "projectPhotos">;
@ -55,7 +55,7 @@ const ProjectForm = ({
const [projectPitchFile, setProjectPitchFile] = useState(""); const [projectPitchFile, setProjectPitchFile] = useState("");
const [tag, setTag] = useState<{ id: number; value: string }[]>([]); const [tag, setTag] = useState<{ id: number; value: string }[]>([]);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [selectedTag, setSelectedTag] = useState(""); const [selectedTag, setSelectedTag] = useState<string[]>([]);
const handleFileChange = ( const handleFileChange = (
event: React.ChangeEvent<HTMLInputElement>, event: React.ChangeEvent<HTMLInputElement>,
@ -485,7 +485,7 @@ const ProjectForm = ({
{/* Tags */} {/* Tags */}
<FormField <FormField
control={form.control} control={form.control}
name="deadline" name="tag"
render={({ field }: { field: any }) => ( render={({ field }: { field: any }) => (
<FormItem> <FormItem>
<div className="mt-10 space-y-5"> <div className="mt-10 space-y-5">
@ -500,29 +500,29 @@ const ProjectForm = ({
aria-expanded={open} aria-expanded={open}
className="w-96 justify-between" className="w-96 justify-between"
> >
{selectedTag {selectedTag.length > 0
? tag.find( ? selectedTag.join(", ")
(framework) => framework.value === selectedTag : "Select tags..."}
)?.value
: "Select framework..."}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" /> <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="w-96 p-0"> <PopoverContent className="w-96 p-0">
<Command> <Command>
<CommandInput placeholder="Search framework..." /> <CommandInput placeholder="Search tags..." />
<CommandList> <CommandList>
<CommandEmpty>No tag found.</CommandEmpty> <CommandEmpty>No tags found.</CommandEmpty>
<CommandGroup> <CommandGroup>
{tag.map((tag) => ( {tag.map((tag) => (
<CommandItem <CommandItem
key={tag.value} key={tag.value}
value={tag.value} value={tag.value}
onSelect={(currentValue) => { onSelect={(currentValue) => {
setSelectedTag( setSelectedTag((prev) =>
currentValue === selectedTag prev.includes(currentValue)
? "" ? prev.filter(
: currentValue (item) => item !== currentValue
)
: [...prev, currentValue]
); );
setOpen(false); setOpen(false);
}} }}
@ -530,7 +530,7 @@ const ProjectForm = ({
<Check <Check
className={cn( className={cn(
"h-4", "h-4",
selectedTag === tag.value selectedTag.includes(tag.value)
? "opacity-100" ? "opacity-100"
: "opacity-0" : "opacity-0"
)} )}
@ -544,10 +544,32 @@ const ProjectForm = ({
</PopoverContent> </PopoverContent>
</Popover> </Popover>
<span className="text-[12px] text-neutral-500 self-center"> <span className="text-[12px] text-neutral-500 self-center">
What is the deadline for your fundraising project? Add 1 to 5 tags that describe your project. Tags help{" "}
Setting <br /> a clear timeline can help motivate <br />
potential investors. investors understand your focus.
</span> </span>
{/* display selected tags */}
<div className="flex flex-wrap space-x-2">
{selectedTag.map((tag) => (
<div
key={tag}
className="flex items-center space-x-1 bg-gray-200 p-1 rounded"
>
<span>{tag}</span>
<button
onClick={() =>
setSelectedTag((prev) =>
prev.filter((item) => item !== tag)
)
}
>
{/* delete button */}
<X className="h-4 w-4" />
</button>
</div>
))}
</div>
</div> </div>
</FormControl> </FormControl>
</div> </div>
@ -555,14 +577,12 @@ const ProjectForm = ({
</FormItem> </FormItem>
)} )}
/> />
<center> <Button
<Button className="mt-12 mb-20 h-10 text-base font-bold py-6 px-5"
className="mt-12 mb-20 h-10 text-base font-bold py-6 px-5" type="submit"
type="submit" >
> Submit application
Submit application </Button>
</Button>
</center>
</div> </div>
</form> </form>
</Form> </Form>

View File

@ -90,6 +90,10 @@ const projectFormSchema = z.object({
.refine((date) => date > new Date(), { .refine((date) => date > new Date(), {
message: "Deadline must be in the future.", message: "Deadline must be in the future.",
}), }),
tag: z
.array(z.string())
.min(1, "Please provide at least one tag.")
.max(5, "You can provide up to 5 tags."),
}); });
const businessFormSchema = z.object({ const businessFormSchema = z.object({