This commit is contained in:
2024-07-19 18:52:14 +05:00
parent b5afd88bdd
commit 726a0924cd
35 changed files with 1093 additions and 48 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

+35
View File
@@ -0,0 +1,35 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useState } from "react";
import CheckIcon from "./icons/CheckIcon";
interface Props {
filterName?: string;
defaultIsChecked?: boolean;
onChange: (isChecked: boolean, filterName: string) => void;
}
function Checkbox2({ filterName, defaultIsChecked, onChange }: Props) {
const [isChecked, setIsChecked] = useState<boolean>(
defaultIsChecked || false
);
function handleClick() {
setIsChecked((prev) => {
onChange(!prev, filterName || "");
return !prev;
});
}
return (
<div
className={`w-6 h-6 rounded flex items-center justify-center text-white cursor-pointer ${
isChecked ? "bg-[#00BED7]" : "bg-[#F3F3F2]"
}`}
onClick={handleClick}
>
{isChecked && <CheckIcon />}
</div>
);
}
export default Checkbox2;
@@ -35,7 +35,7 @@ const MobileSkygardenDescription = ({
</div>
<p className="text-s text-[#73787C] w-full">Indoor</p>
</div>
<p className="text-s text-[#0D1922] text-nowrap">3 amenties</p>
<p className="text-s text-[#0D1922] text-nowrap">3 amenities</p>
</div>
<div className="flex items-center justify-between gap-8">
<div className="flex gap-2 items-center">
@@ -46,7 +46,7 @@ const MobileSkygardenDescription = ({
</div>
<p className="text-s text-[#73787C]">Studio</p>
</div>
<p className="text-s text-[#0D1922] text-nowrap">14 amenties</p>
<p className="text-s text-[#0D1922] text-nowrap">14 amenities</p>
</div>
<Button
@@ -16,18 +16,18 @@ const SkygardenDescription = ({ isLeft }: ISkygardenDescriptionProps) => {
Sky Garden
</p>
<div className="py-[3px] px-2 rounded-full bg-[#00BED7] text-white">
17 amenties
17 amenities
</div>
</div>
<div className="flex flex-col gap-4 pt-4">
<div className="flex items-center justify-between gap-[178px]">
<p className="text-s text-[#73787C] w-full">Indoor</p>
<p className="text-s text-[#0D1922] text-nowrap">3 amenties</p>
<p className="text-s text-[#0D1922] text-nowrap">3 amenities</p>
</div>
<div className="flex items-center justify-between">
<p className="text-s text-[#73787C]">Outdoor </p>
<p className="text-s text-[#0D1922] text-nowrap">14 amenties</p>
<p className="text-s text-[#0D1922] text-nowrap">14 amenities</p>
</div>
</div>
<div
@@ -1,7 +1,7 @@
function SkygardenIndoorLayout() {
return (
<img
src="/images/masterplanWing/skygardenIndoor.png"
src="/images/skyGarden/skyGardenIndoor.jpg"
alt=""
width={672}
height={544}
@@ -1,7 +1,7 @@
const SkygardenOutdoorLayout = () => {
return (
<img
src="/images/masterplanWing/skygardenOutdoor.png"
src="/images/skyGarden/skyGardenOutdoor.jpg"
width={672}
height={544}
alt=""
@@ -44,7 +44,7 @@ const SkygardenSidebar = ({ onMouseEnter }: ISkygardenSidebarProps) => {
<p className="text-s text-[#73787C]">22-23 floor</p>
</div>
<div className="bg-[#00BED7] text-white text-s px-2 py-[3px] rounded-3xl flex h-fit">
<div className="leading-5">17 amenties</div>
<div className="leading-5">17 amenities</div>
</div>
</div>
<div className="overflow-y-scroll py-6 space-y-8">
@@ -53,13 +53,17 @@ const SkygardenSidebar = ({ onMouseEnter }: ISkygardenSidebarProps) => {
<Button
buttonType="secondary"
icon={<VideoIcon />}
text="Sky Garden"
text="Play video"
className="absolute top-6 right-6 px-3.5 py-2.5"
onClick={() => setModal(<VirtualTourVideoModal videoHref="/videos/SkyGarden.mp4" />)}
onClick={() =>
setModal(
<VirtualTourVideoModal videoHref="/videos/SkyGarden.mp4" />
)
}
/>
</div>
<div className="px-6 space-y-4">
<p className="text-xl font-semibold">Indoor Amenties</p>
<p className="text-xl font-semibold">Indoor Amenities</p>
<div className="grid grid-cols-3 gap-4">
<ActivityCard
title={"Indoor Lap Pool"}
@@ -76,7 +80,7 @@ const SkygardenSidebar = ({ onMouseEnter }: ISkygardenSidebarProps) => {
</div>
</div>
<div className="px-6 space-y-4">
<p className="text-xl font-semibold">Outdoor Amenties</p>
<p className="text-xl font-semibold">Outdoor Amenities</p>
<div className="grid grid-cols-3 gap-4">
<ActivityCard title={"Padel Pong"} icon={<PadelPongIcon />} />
<ActivityCard
@@ -8,9 +8,10 @@ import RightArrowSliderIcon from "../../icons/RightArrowSliderIcon";
import { isMobile } from "react-device-detect";
const images: Image[] = [
{ id: "1", src: "/images/company/slider/1.png" },
{ id: "2", src: "/images/company/slider/2.png" },
{ id: "3", src: "/images/company/slider/3.png" },
{ id: "1", src: "/images/skyGardenSlider/1.jpg" },
{ id: "2", src: "/images/skyGardenSlider/2.jpg" },
{ id: "3", src: "/images/skyGardenSlider/3.jpg" },
{ id: "4", src: "/images/skyGardenSlider/4.jpg" },
];
const getGapOffset = (screenWidth: number) => {
@@ -76,7 +77,8 @@ const ZoneSlider = () => {
ref={imageRef}
src={image.src}
alt=""
className="rounded-2xl sm:aspect-[6.6/3.7] object-cover pointer-events-none select-none"
// className="rounded-2xl sm:aspect-[6.6/3.7] object-cover pointer-events-none select-none"
className="rounded-2xl pointer-events-none select-none"
/>
))}
</div>
+11 -6
View File
@@ -1,16 +1,21 @@
const CheckIcon = () => {
interface Props {
className?: string;
}
const CheckIcon = ({ className }: Props) => {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M4.1665 9.16699L8.33317 13.3337L15.8332 6.66699"
d="M5 11L10 16L19 8"
stroke="currentColor"
strokeWidth="1.5"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
+6 -1
View File
@@ -1,4 +1,8 @@
const CrossIcon = () => {
interface Props {
className?: string;
}
const CrossIcon = ({ className }: Props) => {
return (
<svg
width="20"
@@ -6,6 +10,7 @@ const CrossIcon = () => {
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M10.0003 9.99993L14.7144 5.28613M10.0003 9.99993L5.28622 5.28589M10.0003 9.99993L14.7143 14.714M10.0003 9.99993L5.28613 14.714"
+25
View File
@@ -0,0 +1,25 @@
interface Props {
className?: string;
}
function HeartIcon({ className }: Props) {
return (
<svg
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M18.8197 7.15799C17.246 5.614 14.6944 5.614 13.1207 7.15799L12 8.25747L10.8793 7.15799C9.30559 5.614 6.75405 5.614 5.18031 7.15799C3.60656 8.70198 3.60656 11.2053 5.18031 12.7493L12 20L18.8197 12.7493C20.3934 11.2053 20.3934 8.70198 18.8197 7.15799Z"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
/>
</svg>
);
}
export default HeartIcon;
@@ -0,0 +1,25 @@
interface Props {
className?: string;
}
function RestartIcon({ className }: Props) {
return (
<svg
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M14.2607 3.58307L15.8575 2.64711L15.099 1.35303L10.9387 3.79155L13.4608 7.61759L14.7131 6.79204L13.494 4.94248C16.7823 5.62938 19.25 8.53817 19.25 12.0195C19.25 16.0111 16.0058 19.2501 12 19.2501C7.99422 19.2501 4.75 16.0111 4.75 12.0195C4.75 9.90286 5.66096 7.99916 7.11609 6.67555L6.10676 5.56593C4.35276 7.1614 3.25 9.46229 3.25 12.0195C3.25 16.843 7.16922 20.7501 12 20.7501C16.8308 20.7501 20.75 16.843 20.75 12.0195C20.75 7.97647 17.9965 4.57728 14.2607 3.58307Z"
fill="currentColor"
/>
</svg>
);
}
export default RestartIcon;
@@ -14,16 +14,16 @@ const VirtualTourVideoModal = ({ videoHref }: VirtualTourVideoModalProps) => {
return (
<div className="absolute z-[99999999] top-0 left-0 w-screen bg-[#0D192266] h-screen backdrop-blur-[6px] flex justify-center items-center">
<div
className="aspect-video xl:h-[768px] xl:w-auto w-screen relative select-none cursor-pointer"
onClick={handleOnCloseClick}
>
<div className="absolute top-[10px] right-[10px] text-white">
<CrossIcon />
</div>
<div className="aspect-video xl:h-[768px] xl:w-auto w-screen relative select-none">
<video autoPlay muted className="w-full" playsInline preload="metadata">
<source src={videoHref} type="video/mp4" />
</video>
<button
className="absolute top-0 right-0 p-4 text-white"
onClick={handleOnCloseClick}
>
<CrossIcon className="w-8 h-8" />
</button>
</div>
</div>
);
@@ -53,7 +53,7 @@ const initialAparmentTypeCheckboxes: ICheckbox[] = [
const initialViewCheckboxes: ICheckbox[] = [
{ title: "Burj Khalifa", id: "1", selected: false, value: "BK" },
{ title: "Amenties", id: "2", selected: false, value: "Amenities" },
{ title: "Amenities", id: "2", selected: false, value: "Amenities" },
{ title: "Downtown", id: "3", selected: false, value: "DT" },
{ title: "Canal", id: "4", selected: false, value: "Canal" },
{ title: "Business Bay", id: "5", selected: false, value: "Business Bay" },
+2 -1
View File
@@ -35,8 +35,9 @@
}
body {
/* font-family: "Usual"; */
background-color: #f3f3f2;
color: #091118;
color: #0d1922b2;
}
.font-usual {
+3 -2
View File
@@ -9,10 +9,11 @@ import AboutProjectsPage from "./pages/AboutProjectsPage";
import UnitTypesPage from "./pages/UnitTypesPage";
import AboutPage from "./pages/AboutPage";
import FavoritesPage from "./pages/FavoritesPage";
import SearchPage from "./pages/SearchPage";
// import SearchPage from "./pages/SearchPage";
import ApartmentPage from "./pages/ApartmentPage";
import VirtualTour from "./pages/VirtualTour";
import UnitTypesItemPage from "./pages/UnitTypesItemPage";
import SearchPage2 from "./pages/SearchPage2";
const router = createBrowserRouter([
{
@@ -62,7 +63,7 @@ const router = createBrowserRouter([
},
{
path: "search",
element: <SearchPage />,
element: <SearchPage2 />,
},
{
path: "search/:id",
+363
View File
@@ -0,0 +1,363 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useState } from "react";
import RestartIcon from "../components/icons/RestartIcon";
import api from "../utils/api";
import IUnit from "../types/IUnit";
import Checkbox2 from "../components/Checkbox2";
import HeartIcon from "../components/icons/HeartIcon";
function SearchPage2() {
const [units, setUnits] = useState<IUnit[]>([]);
const [filteredUnits, setFilteredUnits] = useState<IUnit[]>([]);
const [unitTypeFilters, setUnitTypeFilters] = useState<string[]>([]);
async function getUnits() {
try {
const result: IUnit[] = await api.get("units").json();
setUnits(result);
} catch (error) {
//
}
}
function getImageSrc(unitNo: string): string {
const side = unitNo.split("-")[0];
const floor = Number(unitNo.split("-")[1].slice(0, -2));
const unitNumber = Number(unitNo.split("-")[1].slice(-2));
if (side === "W") {
// Side "W"
if (floor < 24) {
switch (unitNumber) {
case 1:
return "/images/layouts/2br_a_left.png";
case 2:
return "/images/layouts/studio_left.png";
case 3:
return "/images/layouts/1br_d_left.png";
case 4:
return "/images/layouts/studio_left.png";
case 5:
return "/images/layouts/studio_left.png";
case 6:
return "/images/layouts/1br_d_left.png";
case 7:
return "/images/layouts/1br_a_left.png";
case 8:
return "/images/layouts/1br_a_left.png";
case 9:
return "/images/layouts/studio_flex_left.png";
case 10:
return "/images/layouts/studio_flex_left.png";
case 11:
return "/images/layouts/studio_flex_left.png";
case 12:
return "/images/layouts/studio_flex_left.png";
case 13:
return "/images/layouts/studio_flex_left.png";
case 14:
return "/images/layouts/studio_flex_left.png";
case 15:
return "/images/layouts/1br_c_left.png";
case 16:
return "/images/layouts/1br_c_left.png";
case 17:
return "/images/layouts/2br_b_left.png";
}
} else {
switch (unitNumber) {
case 1:
return "/images/layouts/2br_a_left.png";
case 2:
return "/images/layouts/studio_left.png";
case 3:
return "/images/layouts/1br_d_left.png";
case 4:
return "/images/layouts/studio_left.png";
case 5:
return "/images/layouts/studio_left.png";
case 6:
return "/images/layouts/1br_d_left.png";
case 7:
return "/images/layouts/1br_a_left.png";
case 8:
return "/images/layouts/1br_a_left.png";
case 9:
return "/images/layouts/1br_d_left.png";
case 10:
return "/images/layouts/studio_left.png";
case 11:
return "/images/layouts/studio_left.png";
case 12:
return "/images/layouts/1br_d_left.png";
case 13:
return "/images/layouts/1br_c_left.png";
case 14:
return "/images/layouts/1br_c_left.png";
case 15:
return "/images/layouts/2br_b_left.png";
}
}
} else {
// Side "E"
switch (unitNumber) {
case 1:
return "/images/layouts/2br_a_left.png";
case 2:
return "/images/layouts/studio_left.png";
case 3:
return "/images/layouts/1br_d_left.png";
case 4:
return "/images/layouts/studio_left.png";
case 5:
return "/images/layouts/studio_left.png";
case 6:
return "/images/layouts/1br_c_left.png";
case 7:
return "/images/layouts/1br_c_left.png";
case 8:
return "/images/layouts/1br_b_left.png";
case 9:
return "/images/layouts/1br_b_left.png";
case 10:
return "/images/layouts/1br_c_left.png";
case 11:
return "/images/layouts/studio_left.png";
case 12:
return "/images/layouts/studio_left.png";
case 13:
return "/images/layouts/studio_left.png";
case 14:
return "/images/layouts/studio_left.png";
case 15:
return "/images/layouts/1br_c_left.png";
case 16:
return "/images/layouts/1br_c_left.png";
}
}
console.log(side, floor, unitNumber);
// switch (unitType) {
// case "Studio Squared":
// return "/images/layouts/studio_left.png";
// case "Studio Flex":
// return "/images/layouts/studio_flex_left.png";
// case "1 BR Squared":
// return "/images/layouts/1br_a_left.png";
// case "2 BR Squared":
// return "/images/layouts/2br_a_left.png";
// default:
// return "";
// }
return "";
}
useEffect(() => {
if (unitTypeFilters.length) {
setFilteredUnits(
units.filter((unit) => unitTypeFilters.includes(unit.unitType))
);
} else {
setFilteredUnits([]);
}
}, [unitTypeFilters]);
useEffect(() => {
if (!filteredUnits.length) return;
console.log("filteredUnits", filteredUnits);
}, [filteredUnits]);
useEffect(() => {
getUnits();
});
return (
<div className="pt-[58px] flex select-none">
<div className="p-6 min-w-[360px]">
<div className="flex justify-between">
<p className="text-2xl text-[#0D1922] font-semibold">Filters</p>
<div className="w-10 h-10 bg-white rounded-full flex items-center justify-center">
<RestartIcon className="w-5 h-5" />
</div>
</div>
{/* <div className=""></div> */}
<div className="p-6 space-y-4">
<p>Apartment type</p>
<div className="space-y-2">
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<Checkbox2
filterName="Studio Flex"
onChange={(isChecked, filterName) => {
if (isChecked) {
setUnitTypeFilters((prev) => [...prev, filterName]);
} else {
setUnitTypeFilters(
unitTypeFilters.filter(
(unitTypeFilter) => unitTypeFilter !== filterName
)
);
}
}}
/>
<p>Studio Flex</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
{
units.filter((unit) => unit.unitType === "Studio Flex")
.length
}
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<Checkbox2
filterName="Studio Squared"
onChange={(isChecked, filterName) => {
if (isChecked) {
setUnitTypeFilters((prev) => [...prev, filterName]);
} else {
setUnitTypeFilters(
unitTypeFilters.filter(
(unitTypeFilter) => unitTypeFilter !== filterName
)
);
}
}}
/>
<p>Studio²</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
{
units.filter((unit) => unit.unitType === "Studio Squared")
.length
}
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<Checkbox2
filterName="1 BR Squared"
onChange={(isChecked, filterName) => {
if (isChecked) {
setUnitTypeFilters((prev) => [...prev, filterName]);
} else {
setUnitTypeFilters(
unitTypeFilters.filter(
(unitTypeFilter) => unitTypeFilter !== filterName
)
);
}
}}
/>
<p>1 Bedroom²</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
{
units.filter((unit) => unit.unitType === "1 BR Squared")
.length
}
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<Checkbox2
filterName="2 BR Squared"
onChange={(isChecked, filterName) => {
if (isChecked) {
setUnitTypeFilters((prev) => [...prev, filterName]);
} else {
setUnitTypeFilters(
unitTypeFilters.filter(
(unitTypeFilter) => unitTypeFilter !== filterName
)
);
}
}}
/>
<p>2 Bedroom²</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
{
units.filter((unit) => unit.unitType === "2 BR Squared")
.length
}
</p>
</div>
</div>
</div>
</div>
<div className=""></div>
<div className=""></div>
</div>
<div className="p-6 w-full">
<div className="">
<div className="flex justify-between">
<div className="">
<p className="text-2xl font-semibold">
<span className="text-[#0D1922]">Units</span>{" "}
<span>{filteredUnits.length || units.length}</span>
</p>
</div>
<div className="">
<button className="bg-white rounded px-4 py-2">Sort</button>
</div>
</div>
<div className="grid grid-cols-4 gap-4">
{(filteredUnits.length ? filteredUnits : units).map((unit) => (
<div className="bg-white rounded-2xl p-4 space-y-4">
<div className="flex justify-between">
<div className="space-y-1">
<p className="text-sm text-[#00BED7]">{unit.projectName}</p>
<div className="flex items-center gap-2 text-xs font-semibold">
<p className="">
{unit.unitNo[0] === "E" ? "East" : "West"} Wing
</p>
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
<p>{unit.floor}</p>
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
<p>{unit.unitNo}</p>
</div>
</div>
<button className="w-10 h-10 flex items-center justify-center border border-[#E2E2DC] rounded-full bg-[#FFFFFF] bg-opacity-80 hover:text-[#0D1922] hover:bg-opacity-100 hover:border-[#00BED7] transition-all">
<HeartIcon className="w-5 h-5" />
</button>
</div>
<div className="flex justify-center">
<img
src={getImageSrc(unit.unitNo)}
alt=""
className="max-h-[240px] pointer-events-none"
/>
</div>
<div className="space-y-1">
<p className="text-sm">
{unit.unitType}, {unit.totalArea} Sqft
</p>
<p className="text-xl text-[#00BED7] font-semibold">
{(unit.unitPrice &&
`AED ${unit.unitPrice.toLocaleString()}`) ||
"Unavailable"}
</p>
</div>
</div>
))}
</div>
</div>
</div>
</div>
);
}
export default SearchPage2;
+1 -1
View File
@@ -31,7 +31,7 @@ function UnitTypesItemPage() {
<div className="">
{unitType?.legends.map((legend, index) => (
<div className="flex gap-2 items-center">
<div className="w-4 h-4 bg-[#00BED7] text-white rounded-full text-[10px] font-semibold flex items-center justify-center">
<div className="min-w-4 min-h-4 bg-[#00BED7] text-white rounded-full text-[10px] font-semibold flex items-center justify-center">
{index + 1}
</div>
<p className="text-sm">{legend}</p>
+19
View File
@@ -0,0 +1,19 @@
interface IUnit {
propertyName: string;
projectName: string;
floor: number;
unitNo: string;
propertyStatus: string;
unitType: string;
unitView: string;
furnished: string;
totalArea: number;
suiteArea: number;
balconyArea: number;
bedrooms: number;
bathrooms: number;
parkingSpaces: number;
unitPrice?: number;
}
export default IUnit;
+7
View File
@@ -0,0 +1,7 @@
import ky from "ky";
const api = ky.extend({
prefixUrl: import.meta.env.VITE_SERVER_API,
});
export default api;
+2 -1
View File
@@ -1,2 +1,3 @@
PORT=4002
REFRESH_TOKEN=1000.ca08e1e4dc5fe081e2bd7fdbd0adf5e6.68b8da640d7322a889f10eddbcf5ee6b
REFRESH_TOKEN=1000.ca08e1e4dc5fe081e2bd7fdbd0adf5e6.68b8da640d7322a889f10eddbcf5ee6b
MONGO_URI=mongodb://root:p62Z!ZatgY25@194.26.138.94:27017
+2 -1
View File
@@ -1,5 +1,5 @@
{
"name": "client",
"name": "server",
"private": true,
"version": "0.0.0",
"type": "module",
@@ -12,6 +12,7 @@
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"mongoose": "^8.5.1",
"morgan": "^1.10.0",
"winston": "^3.13.0"
},
+16
View File
@@ -0,0 +1,16 @@
import { connect } from "mongoose";
async function connectDB() {
try {
await connect(process.env.MONGO_URI!, { dbName: "irth" });
console.log("MongoDB connected...");
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
}
process.exit(1);
}
}
export default connectDB;
+302
View File
@@ -0,0 +1,302 @@
[
{
"unitName": "RHMD-8E-06",
"bedrooms": "1 BR Squared",
"floor": 8,
"position": "Front",
"suiteArea": 487,
"balconyArea": 121,
"unitArea": 608,
"unitPrice": 1699888
},
{
"unitName": "RHMD-9E-01",
"bedrooms": "2 BR Squared",
"floor": 9,
"position": "Front",
"suiteArea": 737,
"balconyArea": 177,
"unitArea": 914,
"unitPrice": 2430888
},
{
"unitName": "RHMD-9W-06",
"bedrooms": "1 BR Squared",
"floor": 9,
"position": "Front",
"suiteArea": 496,
"balconyArea": 121,
"unitArea": 618,
"unitPrice": 1732888
},
{
"unitName": "RHMD-9W-15",
"bedrooms": "1 BR Squared",
"floor": 9,
"position": "Back",
"suiteArea": 520,
"balconyArea": 122,
"unitArea": 642,
"unitPrice": 1594888
},
{
"unitName": "RHMD-9W-17",
"bedrooms": "2 BR Squared",
"floor": 9,
"position": "Back",
"suiteArea": 729,
"balconyArea": 328,
"unitArea": " 1 058 ",
"unitPrice": 2364888
},
{
"unitName": "RHMD-11E-14",
"bedrooms": "Studio Squared",
"floor": 11,
"position": "Back",
"suiteArea": 339,
"balconyArea": 78,
"unitArea": 416,
"unitPrice": 1175888
},
{
"unitName": "RHMD-11W-12",
"bedrooms": "Studio Flex",
"floor": 11,
"position": "Back",
"suiteArea": 284,
"balconyArea": 72,
"unitArea": 356,
"unitPrice": 1054888
},
{
"unitName": "RHMD-12W-01",
"bedrooms": "2 BR Squared",
"floor": 12,
"position": "Front",
"suiteArea": 737,
"balconyArea": 177,
"unitArea": 914,
"unitPrice": 2454888
},
{
"unitName": "RHMD-12W-07",
"bedrooms": "1 BR Squared",
"floor": 12,
"position": "Front",
"suiteArea": 492,
"balconyArea": 129,
"unitArea": 622,
"unitPrice": 1784888
},
{
"unitName": "RHMD-12W-13",
"bedrooms": "Studio Flex",
"floor": 12,
"position": "Back",
"suiteArea": 273,
"balconyArea": 68,
"unitArea": 341,
"unitPrice": 1014888
},
{
"unitName": "RHMD-12W-17",
"bedrooms": "2 BR Squared",
"floor": 12,
"position": "Back",
"suiteArea": 729,
"balconyArea": 328,
"unitArea": " 1 058 ",
"unitPrice": 2388888
},
{
"unitName": "RHMD-15W-04",
"bedrooms": "Studio Squared",
"floor": 15,
"position": "Front",
"suiteArea": 320,
"balconyArea": 81,
"unitArea": 401,
"unitPrice": 1294888
},
{
"unitName": "RHMD-15W-16",
"bedrooms": "1 BR Squared",
"floor": 15,
"position": "Back",
"suiteArea": 487,
"balconyArea": 122,
"unitArea": 609,
"unitPrice": 1544888
},
{
"unitName": "RHMD-20E-02",
"bedrooms": "Studio Squared",
"floor": 20,
"position": "Front",
"suiteArea": 325,
"balconyArea": 78,
"unitArea": 403,
"unitPrice": 1339888
},
{
"unitName": "RHMD-21W-04",
"bedrooms": "Studio Squared",
"floor": 21,
"position": "Front",
"suiteArea": 320,
"balconyArea": 81,
"unitArea": 401,
"unitPrice": 1340888
},
{
"unitName": "RHMD-21W-10",
"bedrooms": "Studio Flex",
"floor": 21,
"position": "Back",
"suiteArea": 273,
"balconyArea": 68,
"unitArea": 341,
"unitPrice": 1052888
},
{
"unitName": "RHMD-24E-04",
"bedrooms": "Studio Squared",
"floor": 24,
"position": "Front",
"suiteArea": 320,
"balconyArea": 81,
"unitArea": 401,
"unitPrice": 1366888
},
{
"unitName": "RHMD-24W-10",
"bedrooms": "Studio Squared",
"floor": 24,
"position": "Back",
"suiteArea": 320,
"balconyArea": 81,
"unitArea": 401,
"unitPrice": 1202888
},
{
"unitName": "RHMD-24W-12",
"bedrooms": "1 BR Squared",
"floor": 24,
"position": "Back",
"suiteArea": 501,
"balconyArea": 119,
"unitArea": 619,
"unitPrice": 1605888
},
{
"unitName": "RHMD-25E-15",
"bedrooms": "1 BR Squared",
"floor": 25,
"position": "Back",
"suiteArea": 520,
"balconyArea": 122,
"unitArea": 642,
"unitPrice": 1674888
},
{
"unitName": "RHMD-26E-12",
"bedrooms": "Studio Squared",
"floor": 26,
"position": "Back",
"suiteArea": 319,
"balconyArea": 81,
"unitArea": 400,
"unitPrice": 1216888
},
{
"unitName": "RHMD-26E-14",
"bedrooms": "Studio Squared",
"floor": 26,
"position": "Back",
"suiteArea": 339,
"balconyArea": 78,
"unitArea": 416,
"unitPrice": 1264888
},
{
"unitName": "RHMD-26W-09",
"bedrooms": "1 BR Squared",
"floor": 26,
"position": "Back",
"suiteArea": 500,
"balconyArea": 118,
"unitArea": 618,
"unitPrice": 1624888
},
{
"unitName": "RHMD-26W-14",
"bedrooms": "1 BR Squared",
"floor": 26,
"position": "Back",
"suiteArea": 487,
"balconyArea": 122,
"unitArea": 609,
"unitPrice": 1635888
},
{
"unitName": "RHMD-27E-12",
"bedrooms": "Studio Squared",
"floor": 27,
"position": "Back",
"suiteArea": 319,
"balconyArea": 81,
"unitArea": 400,
"unitPrice": 1224888
},
{
"unitName": "RHMD-27E-13",
"bedrooms": "Studio Squared",
"floor": 27,
"position": "Back",
"suiteArea": 309,
"balconyArea": 78,
"unitArea": 386,
"unitPrice": 1181888
},
{
"unitName": "RHMD-28E-05",
"bedrooms": "Studio Squared",
"floor": 28,
"position": "Front",
"suiteArea": 319,
"balconyArea": 81,
"unitArea": 400,
"unitPrice": 1397888
},
{
"unitName": "RHMD-29W-13",
"bedrooms": "1 BR Squared",
"floor": 29,
"position": "Back",
"suiteArea": 520,
"balconyArea": 122,
"unitArea": 642,
"unitPrice": 1756888
},
{
"unitName": "RHMD-30W-11",
"bedrooms": "Studio Squared",
"floor": 30,
"position": "Back",
"suiteArea": 320,
"balconyArea": 81,
"unitArea": 401,
"unitPrice": 1248888
},
{
"unitName": "RHMD-30W-15",
"bedrooms": "2 BR Squared",
"floor": 30,
"position": "Back",
"suiteArea": 729,
"balconyArea": 328,
"unitArea": " 1 058 ",
"unitPrice": 2730888
}
]
+11 -9
View File
@@ -4,29 +4,31 @@ import cors from "cors";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import connectDB from "./config/db.js";
import morgan from "morgan";
import apartmentsRoute from "./routes/apartments.js";
import apartmentRoute from "./routes/apartment.js";
import updateAccessToken from "./routes/zohoAccessToken.js";
import unitsRoute from "./routes/unitsRoute.js";
// import updateApartmentsRoute from "./routes/updateApartmentsRoute.js";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const port = process.env.PORT || 3000;
!fs.existsSync("logs") && fs.mkdirSync("logs");
const accessLogStream = fs.createWriteStream(
path.join(__dirname, "../logs/access.log"),
{ flags: "a" }
);
await connectDB();
const app = express();
const port = process.env.PORT || 3000;
app.use(cors());
app.use(json());
app.use(morgan("combined", { stream: accessLogStream }));
app.use("/apartments", apartmentsRoute);
app.use("/apartment", apartmentRoute);
app.use("/updateAccessToken", updateAccessToken);
app.use("/units", unitsRoute);
// app.use("/update-apartments", updateApartmentsRoute);
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
+60
View File
@@ -0,0 +1,60 @@
import { model, Schema } from "mongoose";
const unitSchema = new Schema(
{
propertyName: {
type: String,
},
projectName: {
type: String,
},
floor: {
type: Number,
},
unitNo: {
type: String,
},
propertyStatus: {
type: String,
},
unitType: {
type: String,
},
unitView: {
type: String,
},
furnished: {
type: String,
},
totalArea: {
type: Number,
},
suiteArea: {
type: Number,
},
balconyArea: {
type: Number,
},
bedrooms: {
type: Number,
},
bathrooms: {
type: Number,
},
parkingSpaces: {
type: Number,
},
unitPrice: {
type: Number,
},
},
{
timestamps: true,
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
const Unit = model("Unit", unitSchema);
export default Unit;
+28
View File
@@ -0,0 +1,28 @@
import { Router } from "express";
import Unit from "../models/Unit.js";
const router = Router();
router.get("/", async (req, res) => {
try {
const units = await Unit.find();
res.json(units);
} catch (error) {
res.json({ error: (error as Error).message });
}
});
router.get("/:id", async (req, res) => {
try {
const unit = await Unit.findById(req.params.id);
res.json(unit);
} catch (error) {
res.json({ error: (error as Error).message });
}
});
const apartmentRoute = router;
export default apartmentRoute;
@@ -0,0 +1,30 @@
import { Router } from "express";
import data from "../data/irth_unit_pirces.json" assert { type: "json" };
import Unit from "../models/Unit.js";
const router = Router();
router.get("/", async (req, res) => {
for (const item of data) {
const result = await Unit.findOneAndUpdate(
{ propertyName: item.unitName },
{ unitPrice: item.unitPrice },
{ new: true }
);
console.log("result", result);
}
// const file = fs.readFileSync(
// path.resolve("./src/data/irth_unit_pirces.json"),
// { encoding: "utf8" }
// );
// const data = JSON.parse(file);
res.json({ ok: 1 });
});
const updateApartmentsRoute = router;
export default updateApartmentsRoute;
+1 -1
View File
@@ -39,7 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
"resolveJsonModule": true /* Enable importing .json files. */,
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
+114 -1
View File
@@ -41,6 +41,13 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@mongodb-js/saslprep@^1.1.5":
version "1.1.8"
resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz#d39744540be8800d17749990b0da95b4271840d1"
integrity sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==
dependencies:
sparse-bitfield "^3.0.3"
"@tsconfig/node10@^1.0.7":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2"
@@ -159,6 +166,18 @@
resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c"
integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==
"@types/webidl-conversions@*":
version "7.0.3"
resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz#1306dbfa53768bcbcfc95a1c8cde367975581859"
integrity sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==
"@types/whatwg-url@^11.0.2":
version "11.0.5"
resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-11.0.5.tgz#aaa2546e60f0c99209ca13360c32c78caf2c409f"
integrity sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==
dependencies:
"@types/webidl-conversions" "*"
accepts@~1.3.8:
version "1.3.8"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
@@ -252,6 +271,11 @@ braces@~3.0.2:
dependencies:
fill-range "^7.1.1"
bson@^6.7.0:
version "6.8.0"
resolved "https://registry.yarnpkg.com/bson/-/bson-6.8.0.tgz#5063c41ba2437c2b8ff851b50d9e36cb7aaa7525"
integrity sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==
bytes@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
@@ -371,7 +395,7 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
debug@^4:
debug@4.x, debug@^4:
version "4.3.5"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
@@ -652,6 +676,11 @@ is-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
kareem@2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.6.3.tgz#23168ec8ffb6c1abfd31b7169a6fb1dd285992ac"
integrity sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==
kuler@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
@@ -679,6 +708,11 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
memory-pager@^1.0.2:
version "1.5.0"
resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -713,6 +747,36 @@ minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
mongodb-connection-string-url@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz#c13e6ac284ae401752ebafdb8cd7f16c6723b141"
integrity sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==
dependencies:
"@types/whatwg-url" "^11.0.2"
whatwg-url "^13.0.0"
mongodb@6.7.0:
version "6.7.0"
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.7.0.tgz#f86e51e6530e6a2ca4a99d7cfdf6f409223ac199"
integrity sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==
dependencies:
"@mongodb-js/saslprep" "^1.1.5"
bson "^6.7.0"
mongodb-connection-string-url "^3.0.0"
mongoose@^8.5.1:
version "8.5.1"
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.5.1.tgz#011192edf77af54dd0826a836459212da317c503"
integrity sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==
dependencies:
bson "^6.7.0"
kareem "2.6.3"
mongodb "6.7.0"
mpath "0.9.0"
mquery "5.0.0"
ms "2.1.3"
sift "17.1.3"
morgan@^1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7"
@@ -724,6 +788,18 @@ morgan@^1.10.0:
on-finished "~2.3.0"
on-headers "~1.0.2"
mpath@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904"
integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==
mquery@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/mquery/-/mquery-5.0.0.tgz#a95be5dfc610b23862df34a47d3e5d60e110695d"
integrity sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==
dependencies:
debug "4.x"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -829,6 +905,11 @@ pstree.remy@^1.1.8:
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
punycode@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
qs@6.11.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
@@ -948,6 +1029,11 @@ side-channel@^1.0.4:
get-intrinsic "^1.2.4"
object-inspect "^1.13.1"
sift@17.1.3:
version "17.1.3"
resolved "https://registry.yarnpkg.com/sift/-/sift-17.1.3.tgz#9d2000d4d41586880b0079b5183d839c7a142bf7"
integrity sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
@@ -962,6 +1048,13 @@ simple-update-notifier@^2.0.0:
dependencies:
semver "^7.5.3"
sparse-bitfield@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11"
integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==
dependencies:
memory-pager "^1.0.2"
stack-trace@0.0.x:
version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
@@ -1008,6 +1101,13 @@ touch@^3.1.0:
resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694"
integrity sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==
tr46@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-4.1.1.tgz#281a758dcc82aeb4fe38c7dfe4d11a395aac8469"
integrity sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==
dependencies:
punycode "^2.3.0"
triple-beam@^1.3.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984"
@@ -1080,6 +1180,19 @@ vary@^1, vary@~1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
webidl-conversions@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
whatwg-url@^13.0.0:
version "13.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-13.0.0.tgz#b7b536aca48306394a34e44bda8e99f332410f8f"
integrity sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==
dependencies:
tr46 "^4.1.1"
webidl-conversions "^7.0.0"
winston-transport@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.0.tgz#e302e6889e6ccb7f383b926df6936a5b781bd1f0"