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 ( + <> + +
+
+
+ + + {/* */} + +
+
+
+ + ); }; 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",