-
Notifications
You must be signed in to change notification settings - Fork 1
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
1422/finder scaffolding + Q1 #1448
Changes from all commits
f73b0f7
d5bdc3f
1389a85
2ccf612
ceee9d8
7984876
5ae812c
3758018
e43b8f8
e48b436
b73a9ec
b8710b3
c515f31
3522e47
aa0cbc4
c9a2802
8bb47f7
01b8e43
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,213 @@ | ||
import { | ||
encodeToFrontendFilterString, | ||
FrontendListingFilterStateKeys, | ||
ListingFilterState, | ||
} from "@bloom-housing/shared-helpers" | ||
import { | ||
AppearanceStyleType, | ||
Button, | ||
Field, | ||
Form, | ||
FormCard, | ||
ProgressNav, | ||
StepHeader, | ||
t, | ||
} from "@bloom-housing/ui-components" | ||
import axios from "axios" | ||
import router from "next/router" | ||
|
||
import React, { useEffect, useState } from "react" | ||
import { useForm } from "react-hook-form" | ||
import Layout from "../layouts/application" | ||
|
||
interface finderField { | ||
label: string | ||
translation: string | ||
selected: boolean | ||
} | ||
|
||
interface finderQuestion { | ||
fieldGroupName: string | ||
fields: finderField[] | ||
} | ||
|
||
interface finderForm { | ||
[key: number]: finderQuestion | ||
} | ||
|
||
const Finder = () => { | ||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
const { register, handleSubmit, getValues } = useForm() | ||
const [currentStep, setCurrentStep] = useState<number>(1) | ||
const [formData, setFormData] = useState<finderForm>(null) | ||
const activeQuestion = formData?.[currentStep] | ||
|
||
const translationStringMap = { | ||
studio: "studioPlus", | ||
oneBdrm: "onePlus", | ||
twoBdrm: "twoPlus", | ||
threeBdrm: "threePlus", | ||
fourBdrm: "fourPlus", | ||
} | ||
|
||
const stepLabels = [ | ||
t("finder.progress.housingLabel"), | ||
t("t.accessibility"), | ||
t("finder.progress.builingLabel"), | ||
] | ||
|
||
const onSubmit = (data: ListingFilterState) => { | ||
void router.push(`/listings/filtered?page=${1}&limit=${8}${encodeToFrontendFilterString(data)}`) | ||
} | ||
useEffect(() => { | ||
const getAndSetOptions = async () => { | ||
try { | ||
const response = await axios.get(`${process.env.backendApiBase}/listings/meta`) | ||
const formQuestions: finderForm = {} | ||
if (response?.data?.unitTypes) { | ||
const bedroomFields = response.data.unitTypes.map((elem) => ({ | ||
label: elem.name, | ||
translation: translationStringMap[elem.name], | ||
selected: false, | ||
})) | ||
formQuestions[1] = { fieldGroupName: "bedRoomSize", fields: bedroomFields } | ||
} | ||
setFormData(formQuestions) | ||
} catch (e) { | ||
console.error(e) | ||
} | ||
} | ||
void getAndSetOptions() | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []) | ||
|
||
const ProgressHeader = () => { | ||
return ( | ||
<div className="flex flex-col w-full px-2 md:px-0"> | ||
<div className="flex flex-row flex-wrap justify-between gap-y-4 gap-x-0.5"> | ||
<div className="md:text-xl capitalize font-bold"> | ||
{t("listingFilters.buttonTitleExtended")} | ||
</div> | ||
<StepHeader | ||
currentStep={currentStep} | ||
totalSteps={3} | ||
stepPreposition={t("finder.progress.stepPreposition")} | ||
stepLabeling={stepLabels} | ||
></StepHeader> | ||
</div> | ||
<ProgressNav | ||
currentPageSection={currentStep} | ||
completedSections={currentStep - 1} | ||
labels={stepLabels} | ||
mounted={true} | ||
style="bar" | ||
></ProgressNav> | ||
</div> | ||
) | ||
} | ||
|
||
const nextQuestion = () => { | ||
const userSelections = getValues()[formData[currentStep]["fieldGroupName"]] | ||
const formCopy = { ...formData } | ||
formCopy[currentStep]["fields"].forEach( | ||
(field) => (field["selected"] = userSelections.includes(field)) | ||
) | ||
setFormData(formCopy) | ||
setCurrentStep(currentStep + 1) | ||
} | ||
const previousQuestion = () => { | ||
const userSelections = getValues()[formData[currentStep]["fieldGroupName"]] | ||
const formCopy = { ...formData } | ||
formCopy[currentStep]["fields"].forEach( | ||
(field) => (field["selected"] = userSelections.includes(field)) | ||
) | ||
setFormData(formCopy) | ||
setCurrentStep(currentStep - 1) | ||
} | ||
|
||
return ( | ||
<Layout> | ||
<Form onSubmit={handleSubmit(onSubmit)} className="bg-gray-300 border-t border-gray-450"> | ||
<div className="md:mb-8 mt-8 mx-auto max-w-5xl"> | ||
{ProgressHeader()} | ||
<FormCard> | ||
{formData && ( | ||
<> | ||
<div className="px-10 md:px-20 pt-6 md:pt-12 "> | ||
<div className=""> | ||
<div className="text-3xl pb-4"> | ||
{t(`finder.${activeQuestion?.fieldGroupName}.question`)} | ||
</div> | ||
<div className="pb-8 border-b border-gray-450"> | ||
{t("finder.questionSubtitle")} | ||
</div> | ||
</div> | ||
<div className="py-8"> | ||
<p className="pb-4">{t("finder.multiselectHelper")}</p> | ||
<div className="finder-grid"> | ||
{activeQuestion?.fields?.map((field) => { | ||
return ( | ||
<div | ||
className="finder-grid__field" | ||
key={FrontendListingFilterStateKeys[field.label]} | ||
> | ||
<Field | ||
name="bedRoomSize" | ||
register={register} | ||
id={FrontendListingFilterStateKeys[field.label]} | ||
label={t(`listingFilters.bedroomsOptions.${field.translation}`)} | ||
key={FrontendListingFilterStateKeys[field.label]} | ||
type="checkbox" | ||
inputProps={{ | ||
value: FrontendListingFilterStateKeys[field.label], | ||
defaultChecked: field.selected, | ||
}} | ||
bordered | ||
/> | ||
</div> | ||
) | ||
})} | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div className="bg-gray-300 flex flex-row-reverse justify-between py-8 px-20"> | ||
{currentStep === Object.keys(formData).length ? ( | ||
<Button type="submit" styleType={AppearanceStyleType.primary}> | ||
{t("t.submit")} | ||
</Button> | ||
) : ( | ||
<Button | ||
type="button" | ||
onClick={nextQuestion} | ||
styleType={AppearanceStyleType.primary} | ||
> | ||
{t("t.next")} | ||
</Button> | ||
)} | ||
{currentStep > 1 && ( | ||
<Button | ||
type="button" | ||
onClick={previousQuestion} | ||
styleType={AppearanceStyleType.primary} | ||
> | ||
{t("t.back")} | ||
</Button> | ||
)} | ||
</div> | ||
|
||
<div className="flex justify-center align-center bg-white py-8"> | ||
<a className="underline" href="/listings"> | ||
{t("finder.skip")} | ||
</a> | ||
</div> | ||
</> | ||
)} | ||
</FormCard> | ||
</div> | ||
</Form> | ||
</Layout> | ||
) | ||
} | ||
|
||
export default Finder |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
.progress-nav { | ||
padding: 20px 0; | ||
padding-top: 1rem; | ||
padding-bottom: 1.5rem; | ||
@screen md { | ||
padding: 31px 0; | ||
padding-bottom: 3rem; | ||
padding-top: 2rem; | ||
} | ||
} | ||
|
||
|
@@ -45,3 +47,20 @@ li.progress-nav__item { | |
.field-note { | ||
@apply font-normal; | ||
} | ||
|
||
.finder-grid { | ||
display: flex; | ||
flex-wrap: wrap; | ||
justify-content: space-between; | ||
row-gap: 0.5rem; | ||
column-gap: 0.5rem; | ||
.finder-grid__field { | ||
.field { | ||
--leftward-margin: 0rem; | ||
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. 🦑 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. Lol |
||
} | ||
width: 100%; | ||
@screen md { | ||
width: calc(50% - 0.25rem); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -277,7 +277,6 @@ | |
} | ||
|
||
.hero__button { | ||
color: black; | ||
display: inline-block; | ||
font-size: large; | ||
max-width: 100%; | ||
|
@@ -292,14 +291,25 @@ | |
} | ||
} | ||
|
||
.hero__home-button { | ||
.hero__rentals-button { | ||
color: black; | ||
background-color: #ffbe42; | ||
|
||
&:hover { | ||
@apply bg-primary; | ||
color: white; | ||
} | ||
} | ||
.hero__finder-button { | ||
color: var(--bloom-color-white); | ||
background-color: var(--bloom-color-primary-dark); | ||
margin-left: var(--bloom-s2); | ||
&:hover { | ||
color: var(--bloom-color-white); | ||
box-shadow: 0 0 0 var(--bloom-s0_5) var(--bloom-color-primary-dark) inset; | ||
background-color: var(--bloom-color-black); | ||
} | ||
Comment on lines
+307
to
+311
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. The normal Detroit button on hover doesn't go to a darker color, but rather switches to an outlined version. Is this the standard that we want to keep? https://storybook.bloom.exygy.dev/?path=/story/actions-button--detroit-style 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. @ludtkemorgan Talked about this one offline a bit with Jesse and he pointed me to these docs: https://www.figma.com/file/slSZvBKEUduz5ldBiDsIzE/detroit-style-guide?node-id=0%3A33. Seems like storybook dev will need to be updated though to reflect this. |
||
} | ||
|
||
.page-header__title { | ||
font-size: 1.5rem; | ||
|
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.
In mobile view the header and stepHeader doesn't have any padding between it and the site header
![image](https://user-images.githubusercontent.com/42942267/191530965-88ef2b19-58da-40aa-a4af-f6f6a0e0951a.png)