-
Notifications
You must be signed in to change notification settings - Fork 0
implemented company filtering #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
0dc1ad2
1f8c1a3
10df1ef
98838e7
d6e2eb8
8ad90de
5b8f774
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
import { useState } from "react"; | ||
import { useFormContext } from "react-hook-form"; | ||
|
||
import { Button } from "@cooper/ui/button"; | ||
import { FormControl, FormField, FormItem } from "@cooper/ui/form"; | ||
import { useCallback } from "react"; | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectGroup, | ||
SelectItem, | ||
SelectSeparator, | ||
SelectTrigger, | ||
SelectValue, | ||
} from "@cooper/ui/select"; | ||
import { Industry } from "@cooper/db/schema"; | ||
import type { IndustryType, LocationType } from "@cooper/db/schema"; | ||
import { api } from "~/trpc/react"; | ||
import { usePathname, useRouter } from "next/navigation"; | ||
import { z } from "zod"; | ||
|
||
interface SearchBarProps { | ||
industry?: IndustryType; | ||
location?: LocationType; | ||
} | ||
|
||
const _formSchema = z.object({ | ||
searchIndustry: z.string().optional(), | ||
searchLocation: z.string().optional(), | ||
}); | ||
type FormSchema = z.infer<typeof _formSchema>; | ||
|
||
export function CompanySearchBar({ industry, location }: SearchBarProps) { | ||
const form = useFormContext(); | ||
const { handleSubmit, setValue } = form; | ||
const router = useRouter(); | ||
const pathName = usePathname(); | ||
|
||
const [selectedIndustry, setSelectedIndustry] = useState<string | undefined>( | ||
industry, | ||
); | ||
const [selectedLocation, setSelectedLocation] = useState<string | undefined>( | ||
location?.city, | ||
); | ||
const { data: locations = [] } = api.location.list.useQuery(); | ||
|
||
const onSubmit = (data: FormSchema) => { | ||
router.push(pathName + "?" + createQueryString(data)); | ||
}; | ||
|
||
const createQueryString = useCallback( | ||
({ searchIndustry, searchLocation }: FormSchema) => { | ||
const params = new URLSearchParams(); | ||
if (searchIndustry) { | ||
params.set("industry", searchIndustry); | ||
} | ||
if (searchLocation) { | ||
params.set("location", searchLocation); | ||
} | ||
|
||
return params.toString(); | ||
}, | ||
[], | ||
); | ||
|
||
return ( | ||
<div className="flex flex-row w-full justify-between items-center pt-4"> | ||
<div className="text-[30px] justify-left">Browse Companies</div> | ||
<div className="flex flex-row gap-6 min-w-0"> | ||
<FormField | ||
control={form.control} | ||
name="searchIndustry" | ||
render={({ field }) => ( | ||
<FormItem className="col-span-5 lg:col-span-2"> | ||
<FormControl> | ||
<Select | ||
onValueChange={(value) => { | ||
setSelectedIndustry(value); | ||
const finalValue = value === "INDUSTRY" ? undefined : value; | ||
setValue(field.name, finalValue); | ||
void handleSubmit(onSubmit)(); | ||
}} | ||
value={selectedIndustry} | ||
> | ||
<SelectTrigger className="h-12 w-[340px] rounded-none border-2 border-l-0 border-t-0 border-[#9A9A9A] text-lg placeholder:opacity-50 focus:ring-0 active:ring-0 lg:rounded-md lg:border-2"> | ||
<SelectValue placeholder="Industry" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectGroup> | ||
<SelectItem className="font-bold" value="INDUSTRY"> | ||
Industry | ||
</SelectItem> | ||
<SelectSeparator /> | ||
{Object.entries(Industry).map(([key, value]) => ( | ||
<SelectItem key={value} value={value}> | ||
{key.charAt(0) + key.slice(1).toLowerCase()} | ||
</SelectItem> | ||
))} | ||
</SelectGroup> | ||
</SelectContent> | ||
</Select> | ||
</FormControl> | ||
</FormItem> | ||
)} | ||
/> | ||
<FormField | ||
control={form.control} | ||
name="searchLocation" | ||
render={({ field }) => ( | ||
<FormItem className="col-span-5 lg:col-span-2"> | ||
<FormControl> | ||
<Select | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We will probably need to replace this select with the Combobox mentioned above. |
||
onValueChange={(value) => { | ||
setSelectedLocation(value); | ||
const finalValue = value === "LOCATION" ? undefined : value; | ||
setValue(field.name, finalValue); | ||
void handleSubmit(onSubmit)(); | ||
}} | ||
value={selectedLocation} | ||
> | ||
<SelectTrigger className="h-12 w-[340px] rounded-none border-2 border-l-0 border-t-0 border-[#9A9A9A] text-lg placeholder:opacity-50 focus:ring-0 active:ring-0 lg:rounded-md lg:border-2"> | ||
<SelectValue placeholder="Location" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectGroup> | ||
<SelectItem className="font-bold" value="LOCATION"> | ||
Location | ||
</SelectItem> | ||
<SelectSeparator /> | ||
{locations.map((location: LocationType) => ( | ||
<SelectItem key={location.id} value={location.id}> | ||
{location.city + ", " + location.state} | ||
</SelectItem> | ||
))} | ||
</SelectGroup> | ||
</SelectContent> | ||
</Select> | ||
</FormControl> | ||
</FormItem> | ||
)} | ||
/> | ||
<Button | ||
className="bg-white hover:bg-white hover:text-[#9A9A9A] border-white text-black" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we can make the text color here the same as the border color you used above to match the figma |
||
onClick={() => { | ||
setSelectedIndustry("INDUSTRY"); | ||
setSelectedLocation("LOCATION"); | ||
form.setValue("searchIndustry", undefined); | ||
form.setValue("searchLocation", undefined); | ||
}} | ||
> | ||
Clear | ||
</Button> | ||
</div> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,12 +6,18 @@ | |
import { useForm } from "react-hook-form"; | ||
import { z } from "zod"; | ||
|
||
import { WorkEnvironment, WorkTerm } from "@cooper/db/schema"; | ||
import { | ||
IndustryType, | ||
LocationType, | ||
WorkEnvironment, | ||
WorkTerm, | ||
} from "@cooper/db/schema"; | ||
import { cn } from "@cooper/ui"; | ||
import { Form } from "@cooper/ui/form"; | ||
|
||
import { ReviewSearchBar } from "~/app/_components/search/review-search-bar"; | ||
import { SimpleSearchBar } from "./simple-search-bar"; | ||
import { CompanySearchBar } from "./company-search-bar"; | ||
|
||
const formSchema = z.object({ | ||
searchText: z.string(), | ||
|
@@ -25,6 +31,8 @@ | |
message: "Invalid cycle type", | ||
}) | ||
.optional(), | ||
searchIndustry: z.string().optional(), | ||
searchLocation: z.string().optional(), | ||
}); | ||
|
||
export type SearchFilterFormType = typeof formSchema; | ||
|
@@ -35,7 +43,9 @@ | |
term?: "INPERSON" | "HYBRID" | "REMOTE"; | ||
alternatePathname?: string; | ||
searchClassName?: string; | ||
searchType?: "REVIEWS" | "SIMPLE"; | ||
searchType?: "REVIEWS" | "SIMPLE" | "COMPANIES"; | ||
industry?: IndustryType; | ||
location?: LocationType; | ||
} | ||
|
||
/** | ||
|
@@ -51,6 +61,8 @@ | |
alternatePathname, | ||
searchClassName, | ||
searchType = "SIMPLE", | ||
industry, | ||
location, | ||
}: SearchFilterProps) { | ||
const form = useForm<z.infer<typeof formSchema>>({ | ||
resolver: zodResolver(formSchema), | ||
|
@@ -65,9 +77,9 @@ | |
const pathName = usePathname(); | ||
|
||
const createQueryString = useCallback( | ||
({ searchText, searchCycle, searchTerm }: z.infer<typeof formSchema>) => { | ||
({ searchCycle, searchTerm }: z.infer<typeof formSchema>) => { | ||
// Initialize URLSearchParams with the required searchText | ||
const params = new URLSearchParams({ search: searchText }); | ||
const params = new URLSearchParams(); | ||
|
||
// Conditionally add searchCycle and searchTerm if they have values | ||
if (searchCycle) { | ||
|
@@ -77,9 +89,9 @@ | |
params.set("term", searchTerm); | ||
} | ||
|
||
return params.toString(); // Returns a query string, e.g., "search=yo&cycle=SPRING" | ||
return params.toString(); | ||
}, | ||
[], | ||
[searchType], | ||
); | ||
|
||
function onSubmit(values: z.infer<typeof formSchema>) { | ||
|
@@ -94,13 +106,16 @@ | |
<Form {...form}> | ||
<form | ||
onSubmit={form.handleSubmit(onSubmit)} | ||
className={cn("w-[100vw]", searchClassName)} | ||
className={cn("w-[90vw]", searchClassName)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now the Clear button doesn't align with the right hand side of the screen like it does with the figma ![]() One solution I found (which also preserves the old styles) is
Let me know if the |
||
> | ||
<div className={cn("flex justify-center")}> | ||
{searchType === "SIMPLE" && <SimpleSearchBar />} | ||
{searchType === "REVIEWS" && ( | ||
<ReviewSearchBar cycle={cycle} term={term} /> | ||
)} | ||
{searchType === "COMPANIES" && ( | ||
<CompanySearchBar industry={industry} location={location} /> | ||
)} | ||
</div> | ||
</form> | ||
</Form> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,7 @@ export function SimpleSearchBar() { | |
const newLocal = | ||
"h-12 border border-l-0 border-cooper-blue-800 text-lg text-cooper-blue-600 placeholder:text-cooper-blue-600 rounded-r-lg rounded-l-none"; | ||
return ( | ||
<div className="flex w-full rounded-lg"> | ||
<div className="flex w-full rounded-lg w-full"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like there are two |
||
<Button | ||
className="h-12 rounded-l-lg rounded-r-none border border-l border-r-0 border-t border-cooper-blue-800 bg-white p-0 px-2 text-lg hover:bg-cooper-blue-200 focus:border-r-0 focus:ring-0 active:ring-0" | ||
type="submit" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is causing the extreme latency which I'm seeing on the preview deployment. I think Tracy has solved this problem though. Spend some time looking through
review-section.tsx
in the form to see how Tracy implemented a Locations combobox.This should help with the problems we are facing right now. Once we get that figured out I can review (it is too slow to test right now)