diff --git a/backend/src/controllers/units.ts b/backend/src/controllers/units.ts
index 56cd12d..b7f9d8a 100644
--- a/backend/src/controllers/units.ts
+++ b/backend/src/controllers/units.ts
@@ -4,7 +4,7 @@ import createHttpError from "http-errors";
import { asyncHandler } from "./wrappers";
import { UnitModel } from "@/models/units";
-import { getUnitReferrals } from "@/services/referral";
+import { deleteUnitReferrals, getUnitReferrals } from "@/services/referral";
import {
EditUnitBody,
FilterParams,
@@ -34,9 +34,13 @@ export const deleteUnitsHandler: RequestHandler = asyncHandler(async (req, res,
const response = await deleteUnit(id);
if (response === null) {
res.status(400);
- } else {
- res.status(200).json(response);
}
+ const referral = await deleteUnitReferrals(id);
+ if (referral === null) {
+ res.status(400);
+ }
+
+ res.status(200).json(response);
});
export const getUnitsHandler: RequestHandler = asyncHandler(async (req, res, _) => {
diff --git a/backend/src/services/referral.ts b/backend/src/services/referral.ts
index b90a744..d7820d0 100644
--- a/backend/src/services/referral.ts
+++ b/backend/src/services/referral.ts
@@ -85,6 +85,10 @@ export async function editReferral(
return referral;
}
+export async function deleteUnitReferrals(unitId: string) {
+ return await ReferralModel.deleteMany({ unit: unitId });
+}
+
export async function deleteReferral(id: string) {
return await ReferralModel.deleteOne({ _id: id });
}
diff --git a/backend/src/validators/units.ts b/backend/src/validators/units.ts
index c356e60..0f934cf 100644
--- a/backend/src/validators/units.ts
+++ b/backend/src/validators/units.ts
@@ -24,7 +24,9 @@ const createUnitSchema = [
.exists()
.withMessage("is required")
.isString()
- .withMessage("must be a string"),
+ .withMessage("must be a string")
+ .notEmpty()
+ .withMessage("cannot be empty"),
body("streetAddress")
.exists()
.withMessage("is required")
diff --git a/frontend/public/plus_sign.svg b/frontend/public/plus_sign.svg
index 09102b7..e92579c 100644
--- a/frontend/public/plus_sign.svg
+++ b/frontend/public/plus_sign.svg
@@ -1,3 +1,3 @@
-
+
\ No newline at end of file
diff --git a/frontend/src/components/FilterDropdown.tsx b/frontend/src/components/FilterDropdown.tsx
index b3c9f88..8bcf259 100644
--- a/frontend/src/components/FilterDropdown.tsx
+++ b/frontend/src/components/FilterDropdown.tsx
@@ -1,7 +1,11 @@
import { useContext } from "react";
+import { useNavigate } from "react-router-dom";
import styled from "styled-components";
+import { Button } from "./Button";
+
import { SortDropDownComp } from "@/components/SortDropDown";
+import { DataContext } from "@/contexts/DataContext";
import { FiltersContext } from "@/pages/Home";
const AllFiltersContainer = styled.div`
@@ -17,7 +21,7 @@ const FiltersFirstRow = styled.div`
flex-direction: row;
justify-content: flex-start;
align-items: center;
- gap: 28px;
+ gap: 33px;
flex-wrap: wrap;
`;
@@ -59,6 +63,20 @@ const SearchBarContainer = styled.div`
box-shadow: 1px 1px 2px 0px rgba(188, 186, 183, 0.4);
`;
+const AddListings = styled(Button)`
+ height: 44px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 6px;
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 150%;
+ letter-spacing: 0.32px;
+ padding: 8px 20px;
+`;
+
export type FilterDropdownProps = {
searchText: string;
sortIndex: number;
@@ -66,6 +84,8 @@ export type FilterDropdownProps = {
export const FilterDropdown = (props: FilterDropdownProps) => {
const { filters, setFilters } = useContext(FiltersContext);
+ const navigate = useNavigate();
+ const dataContext = useContext(DataContext);
return (
@@ -80,6 +100,17 @@ export const FilterDropdown = (props: FilterDropdownProps) => {
/>
+ {dataContext.currentUser?.isHousingLocator && (
+ {
+ navigate("/new-listing");
+ }}
+ >
+
+ Listing
+
+ )}
{
}}
initialSelection={referral.assignedHousingLocator}
options={allReferringStaff}
+ isTableDropdown={true}
/>
);
}
@@ -215,6 +216,7 @@ export const ReferralTable = (props: ReferralTableProps) => {
}}
initialSelection={assignedReferringStaff}
options={allReferringStaff}
+ isTableDropdown={true}
/>,
HLSection(referral),
{
- const navigate = useNavigate();
-
- const dataContext = useContext(DataContext);
-
return (
<>
@@ -69,16 +41,6 @@ export const UnitCardGrid = ({
))}
{units.length === 0 && No matching units found}
- {dataContext.currentUser?.isHousingLocator && (
- {
- navigate("/new-listing");
- }}
- >
-
- Listings
-
- )}
>
);
};
diff --git a/frontend/src/components/UserDropdown.tsx b/frontend/src/components/UserDropdown.tsx
index d916a7b..cfd8b9d 100644
--- a/frontend/src/components/UserDropdown.tsx
+++ b/frontend/src/components/UserDropdown.tsx
@@ -10,9 +10,9 @@ const SearchContainer = styled.div`
position: relative;
`;
-const Icon = styled.img`
+const Icon = styled.img<{ isTableDropdown?: boolean }>`
position: absolute;
- top: 10px;
+ top: ${(props) => (props.isTableDropdown ? "12px" : "10px")};
right: 10px;
`;
@@ -88,6 +88,7 @@ type SelectProps = {
onSelect: (value: Option) => void; //callback function for parent, sends current selected user
reset?: boolean;
isRCDropdown?: boolean;
+ isTableDropdown?: boolean;
};
export function UserDropdown({
@@ -98,6 +99,7 @@ export function UserDropdown({
onSelect,
reset,
isRCDropdown,
+ isTableDropdown,
}: SelectProps) {
const [openMenu, setOpenMenu] = useState(false);
const [searchValue, setSearchValue] = useState(""); //current text value in select input box
@@ -222,7 +224,11 @@ export function UserDropdown({
)}
-
+ {isTableDropdown ? (
+
+ ) : (
+
+ )}
);
}
diff --git a/frontend/src/pages/RenterCandidatePage.tsx b/frontend/src/pages/RenterCandidatePage.tsx
index bc53177..a4deff6 100644
--- a/frontend/src/pages/RenterCandidatePage.tsx
+++ b/frontend/src/pages/RenterCandidatePage.tsx
@@ -387,6 +387,7 @@ export function RenterCandidatePage() {
},
});
}}
+ isTableDropdown={true}
/>
);
}
@@ -657,6 +658,7 @@ export function RenterCandidatePage() {
},
});
}}
+ isTableDropdown={true}
/>,
HLSection(referral),
diff --git a/frontend/src/pages/UnitDetails.tsx b/frontend/src/pages/UnitDetails.tsx
index 6a17c6a..d5820f1 100644
--- a/frontend/src/pages/UnitDetails.tsx
+++ b/frontend/src/pages/UnitDetails.tsx
@@ -46,7 +46,7 @@ const Column = styled.div`
flex-direction: column;
background-color: #fbf7f3;
justify-content: evenly-spaced;
- gap: 16px;
+ gap: 8px;
`;
const HLActions = styled(Column)`
@@ -59,7 +59,7 @@ const DetailsRow = styled(Row)`
const SectionColumn = styled(Column)`
width: 50%;
- gap: 25px;
+ gap: 10px;
`;
const MainColumn = styled.div`
@@ -69,7 +69,7 @@ const MainColumn = styled.div`
`;
const DetailsColumn = styled(MainColumn)`
- margin: 32px 96px;
+ margin: 32px 150px;
gap: 40px;
`;
@@ -90,7 +90,6 @@ const Header = styled.div`
font-family: "Neutraface Text";
line-height: 150%;
line-spacing: 0.64px;
- margin-top: 32px;
`;
const Text = styled.div`
@@ -101,13 +100,8 @@ const Text = styled.div`
letter-spacing: 0.4px;
`;
-const List = styled.ul`
- margin-top: 0;
- margin-bottom: 0;
- padding: 0, 0, 0, 10%;
-`;
-
const StrongText = styled(Text)`
+ margin-top: 15px;
font-weight: 600;
line-height: 30px;
letter-spacing: 0.4px;
@@ -116,17 +110,23 @@ const StrongText = styled(Text)`
const ListText = styled.li`
font-family: "Montserrat";
font-weight: 400;
- font-size: 20px;
+ font-size: 18px;
line-height: 150%
- letter-spacing: 0.4px;
- margin-left: 6%;
+ letter-spacing: 0.32px;
+ margin-left: 3%;
flex-wrap: wrap;
margin-right: 10px;
`;
-const Address = styled(Header)`
+const Address = styled.a`
+ font-size: 32px;
+ font-weight: 700;
+ font-family: "Neutraface Text";
+ line-height: 150%;
+ line-spacing: 0.64px;
padding: 0;
margin: 0 0 5px 0;
+ color: black;
`;
const Availability = styled(Header)`
@@ -333,6 +333,11 @@ const CarouselVideo = styled.video`
padding: 0px 7.5px;
`;
+const SectionBreak = styled.hr`
+ background-color: #cdcaca;
+ height: 1px;
+ border: none;
+`;
type UnitDetailsLocationState = { filters: FilterParams; prevPage: string };
export function UnitDetails() {
@@ -532,11 +537,15 @@ export function UnitDetails() {
{rule}
));
+ const phone = unit.landlordPhone.match(/\d+/g)?.join("");
+
const HousingLocatorComponent = () => {
return (
Landlord: {unit.landlordFirstName + " " + unit.landlordLastName}
- {unit.landlordPhone}
+ {`(${phone?.substring(0, 3)}) ${phone?.substring(3, 6)}-${phone?.substring(
+ 6,
+ )}`}
{unit.landlordEmail}
);
@@ -658,7 +667,12 @@ export function UnitDetails() {
${unit.monthlyRent}/month
- {unit.listingAddress}
+
+ {unit.listingAddress}
+
{currentUser?.isHousingLocator && (
@@ -701,21 +715,17 @@ export function UnitDetails() {
Security Deposit:
-
- ${unit.securityDeposit}
-
+ ${unit.securityDeposit}
Payment/Renting Criteria:
{rentingCriteria}
Application Fee:
-
- ${unit.applicationFeeCost}
-
+ ${unit.applicationFeeCost}
-
+
@@ -732,7 +742,7 @@ export function UnitDetails() {
{utilities}
Housing Authority:
{unit.housingAuthority}
- Additional Comments from Landlord:
+ Comments from Landlord:
{unit.landlordComments}
@@ -748,6 +758,7 @@ export function UnitDetails() {
{unit.approved && (
<>
+
@@ -765,12 +776,14 @@ export function UnitDetails() {
+
{" "}
>
)}
{!unit.approved && (
<>
+
{