From 0b1c9aaa02ece4c707b54f4fe09c64805985073e Mon Sep 17 00:00:00 2001
From: Brad Traversy
Date: Wed, 10 Jul 2024 07:38:50 -0400
Subject: [PATCH] Property listing pages
---
_theme_files/property.html | 7 +-
app/properties/[id]/page.jsx | 107 ++++++++++++++++++++++++++++-
app/properties/page.jsx | 2 +-
components/PropertyDetails.jsx | 99 ++++++++++++++++++++++++++
components/PropertyHeaderImage.jsx | 22 ++++++
package-lock.json | 61 +++++++++++++++-
package.json | 5 +-
properties.json | 10 ---
8 files changed, 292 insertions(+), 21 deletions(-)
create mode 100644 components/PropertyDetails.jsx
create mode 100644 components/PropertyHeaderImage.jsx
diff --git a/_theme_files/property.html b/_theme_files/property.html
index 2c77b95..53be787 100644
--- a/_theme_files/property.html
+++ b/_theme_files/property.html
@@ -356,12 +356,7 @@
This is a beautiful apartment located near the commons
-
-
- We have a beautiful apartment located near the commons. It is a
- 2 bedroom apartment with a full kitchen and bathroom. It is
- available for weekly or monthly rentals.
-
+
diff --git a/app/properties/[id]/page.jsx b/app/properties/[id]/page.jsx
index ff7fa43..58c9f3e 100644
--- a/app/properties/[id]/page.jsx
+++ b/app/properties/[id]/page.jsx
@@ -1,4 +1,107 @@
-const PropertyPage = () => {
- return
PropertyPage
;
+import PropertyHeaderImage from '@/components/PropertyHeaderImage';
+import PropertyDetails from '@/components/PropertyDetails';
+import connectDB from '@/config/database';
+import Property from '@/models/Property';
+
+const PropertyPage = async ({ params }) => {
+ await connectDB();
+ const property = await Property.findById(params.id).lean();
+
+ return (
+ <>
+
+
+
+
+
+
+ {/* */}
+
+
+ Bookmark Property
+
+
+ Share Property
+
+
+ {/* */}
+
+
+ Contact Property Manager
+
+
+
+
+
+
+
+ >
+ );
};
export default PropertyPage;
diff --git a/app/properties/page.jsx b/app/properties/page.jsx
index da4447b..661b697 100644
--- a/app/properties/page.jsx
+++ b/app/properties/page.jsx
@@ -4,7 +4,7 @@ import connectDB from '@/config/database';
const PropertiesPage = async () => {
await connectDB();
- const properties = await Property.find({});
+ const properties = await Property.find({}).lean();
return (
diff --git a/components/PropertyDetails.jsx b/components/PropertyDetails.jsx
new file mode 100644
index 0000000..9a118e3
--- /dev/null
+++ b/components/PropertyDetails.jsx
@@ -0,0 +1,99 @@
+import {
+ FaBed,
+ FaBath,
+ FaRulerCombined,
+ FaTimes,
+ FaCheck,
+ FaMapMarker,
+} from 'react-icons/fa';
+
+const PropertyDetails = ({ property }) => {
+ return (
+
+
+
{property.type}
+
{property.name}
+
+
+
+ {property.location.street}, {property.location.city}{' '}
+ {property.location.state}
+
+
+
+
+ Rates & Options
+
+
+
+
Nightly
+
+ {property.rates.nightly ? (
+ `$${property.rates.nightly.toLocaleString()}`
+ ) : (
+
+ )}
+
+
+
+
Weekly
+
+ {property.rates.weekly ? (
+ `$${property.rates.weekly.toLocaleString()}`
+ ) : (
+
+ )}
+
+
+
+
Monthly
+
+ {property.rates.monthly ? (
+ `$${property.rates.monthly.toLocaleString()}`
+ ) : (
+
+ )}
+
+
+
+
+
+
+
Description & Details
+
+
+ {property.beds}{' '}
+ Beds
+
+
+ {property.baths}{' '}
+ Baths
+
+
+
+ {property.square_feet}{' '}
+ sqft
+
+
+
{property.description}
+
+
+
+
Amenities
+
+
+ {property.amenities.map((amenity, index) => (
+
+ {amenity}
+
+ ))}
+
+
+
+
+ );
+};
+
+export default PropertyDetails;
diff --git a/components/PropertyHeaderImage.jsx b/components/PropertyHeaderImage.jsx
new file mode 100644
index 0000000..717f103
--- /dev/null
+++ b/components/PropertyHeaderImage.jsx
@@ -0,0 +1,22 @@
+import Image from 'next/image';
+
+const PropertyHeaderImage = ({ image }) => {
+ return (
+
+ );
+};
+export default PropertyHeaderImage;
diff --git a/package-lock.json b/package-lock.json
index 76d9b2b..9ca6c05 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,8 +17,11 @@
"react-spinners": "^0.14.1"
},
"devDependencies": {
+ "@types/node": "20.14.10",
+ "@types/react": "18.3.3",
"postcss": "^8",
- "tailwindcss": "^3.4.1"
+ "tailwindcss": "^3.4.1",
+ "typescript": "5.5.3"
}
},
"node_modules/@alloc/quick-lru": {
@@ -329,6 +332,34 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@types/node": {
+ "version": "20.14.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz",
+ "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.12",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
+ "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.3",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
+ "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.0.2"
+ }
+ },
"node_modules/@types/webidl-conversions": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
@@ -593,6 +624,13 @@
"node": ">=4"
}
},
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/debug": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
@@ -2028,6 +2066,27 @@
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
"license": "0BSD"
},
+ "node_modules/typescript": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
+ "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/package.json b/package.json
index b6349f6..359b759 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,10 @@
"react-spinners": "^0.14.1"
},
"devDependencies": {
+ "@types/node": "20.14.10",
+ "@types/react": "18.3.3",
"postcss": "^8",
- "tailwindcss": "^3.4.1"
+ "tailwindcss": "^3.4.1",
+ "typescript": "5.5.3"
}
}
diff --git a/properties.json b/properties.json
index b06d8f1..6ef4a21 100644
--- a/properties.json
+++ b/properties.json
@@ -1,6 +1,5 @@
[
{
- "_id": "1",
"owner": "1",
"name": "Boston Commons Retreat",
"type": "Apartment",
@@ -45,7 +44,6 @@
"updatedAt": "2024-01-01T00:00:00.000Z"
},
{
- "_id": "2",
"owner": "1",
"name": "Cozy Downtown Loft",
"type": "Apartment",
@@ -89,7 +87,6 @@
"updatedAt": "2024-01-02T00:00:00.000Z"
},
{
- "_id": "3",
"owner": "2",
"name": "Luxury Condo with a View",
"type": "Condo",
@@ -135,7 +132,6 @@
"updatedAt": "2024-01-03T00:00:00.000Z"
},
{
- "_id": "4",
"owner": "2",
"name": "Charming Cottage Getaway",
"type": "Cottage Or Cabin",
@@ -169,7 +165,6 @@
"updatedAt": "2024-01-04T00:00:00.000Z"
},
{
- "_id": "5",
"owner": "3",
"name": "Modern Downtown Studio",
"type": "Studio",
@@ -205,7 +200,6 @@
"updatedAt": "2024-01-05T00:00:00.000Z"
},
{
- "_id": "6",
"owner": "3",
"name": "Seaside Retreat",
"type": "House",
@@ -241,7 +235,6 @@
"updatedAt": "2024-01-06T00:00:00.000Z"
},
{
- "_id": "7",
"owner": "4",
"name": "Rustic Cabin in the Woods",
"type": "Cottage Or Cabin",
@@ -276,7 +269,6 @@
"updatedAt": "2024-01-07T00:00:00.000Z"
},
{
- "_id": "8",
"owner": "5",
"name": "Ski-In/Ski-Out Chalet",
"type": "Chalet",
@@ -311,7 +303,6 @@
"updatedAt": "2024-01-08T00:00:00.000Z"
},
{
- "_id": "9",
"owner": "6",
"name": "Mountain View Retreat",
"type": "House",
@@ -347,7 +338,6 @@
"updatedAt": "2024-01-09T00:00:00.000Z"
},
{
- "_id": "10",
"owner": "7",
"name": "Historic Downtown Loft",
"type": "Apartment",