Compare commits

...
10 Commits
Author SHA1 Message Date
admin d934c5487b first commit 2026-08-24 20:16:29 +08:00
Will Adams 3fc55eac72 Brad style prettier config 2025-10-05 09:28:22 +01:00
Will Adams e66bab01e9 Add missing default export of component 2025-10-05 09:27:56 +01:00
Will Adams be5ede92bd correction: map over array to convert 2024-08-31 12:06:29 +01:00
Brad Traversy 2580d7d2b4 Update README.md 2024-07-29 13:17:57 -04:00
Brad Traversy 456b142943 .env example file 2024-07-29 11:43:45 -04:00
Brad Traversy 1789015432 Submit message button 2024-07-26 09:43:28 -04:00
Brad Traversy f5c034201a Theme files changes 2024-07-26 09:41:20 -04:00
Brad Traversy b63e92b486 Properties JSON sample data 2024-07-19 16:25:25 -04:00
Brad Traversy 5a51ccd0b3 Hero markup in theme 2024-07-19 12:46:55 -04:00
87 changed files with 559 additions and 147 deletions
+13
View File
@@ -0,0 +1,13 @@
NEXT_PUBLIC_DOMAIN=http://localhost:3000
NEXT_PUBLIC_API_DOMAIN=http://localhost:3000/api
MONGODB_URI=ADD_YOUR_OWN
GOOGLE_CLIENT_ID=ADD_YOUR_OWN
GOOGLE_CLIENT_SECRET=ADD_YOUR_OWN
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_URL_INTERNAL=http://localhost:3000
NEXTAUTH_SECRET=ADD_YOUR_OWN
CLOUDINARY_CLOUD_NAME=ADD_YOUR_OWN
CLOUDINARY_API_KEY=ADD_YOUR_OWN
CLOUDINARY_API_SECRET=ADD_YOUR_OWN
NEXT_PUBLIC_MAPBOX_TOKEN=ADD_YOUR_OWN
NEXT_PUBLIC_GOOGLE_GEOCODING_API_KEY=ADD_YOUR_OWN
+13
View File
@@ -0,0 +1,13 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"bracketSpacing": true,
"bracketSameLine": false,
"jsxSingleQuote": true,
"trailingComma": "es5",
"arrowParens": "avoid"
}
+2
View File
@@ -4,6 +4,8 @@
This is the main project from my [Next 14 From Scratch Course](https://www.traversymedia.com/nextjs-from-scratch)
This is the second iteration of the app/course that uses server actions instead of API routes.
The `_theme_files` folder contains the pure HTML files with Tailwind classes.
<img src="/public/images/screen.jpg" />
+7 -24
View File
@@ -231,23 +231,6 @@
</p>
</div>
<!-- Form Component -->
<!-- <form class="mt-10 mx-auto max-w-lg w-full flex items-center">
<div class="flex-1">
<label for="location" class="sr-only">Location</label>
<input
type="text"
id="location"
placeholder="Enter Location"
class="w-full px-4 py-3 rounded-lg bg-white text-gray-800 focus:outline-none focus:ring focus:ring-blue-500"
/>
</div>
<button
type="submit"
class="ml-4 px-4 py-3 rounded-lg bg-blue-500 text-white hover:bg-blue-600 focus:outline-none focus:ring focus:ring-blue-500"
>
Search
</button>
</form> -->
<form
class="mt-3 mx-auto max-w-2xl w-full flex flex-col md:flex-row items-center"
>
@@ -334,7 +317,7 @@
<img
src="images/properties/f1.jpg"
alt=""
class="object-cover rounded-t-xl md:rounded-tr-none md:rounded-l-xl w-full md:w-2/5"
class="w-full h-auto rounded-t-xl md:rounded-tr-none md:rounded-l-xl w-full md:w-2/5"
/>
<div class="p-6">
<h3 class="text-xl font-bold">Seaside Retreat</h3>
@@ -388,9 +371,9 @@
class="bg-white rounded-xl shadow-md relative flex flex-col md:flex-row"
>
<img
src="images/properties/e1.jpg"
src="/images/properties/e1.jpg"
alt=""
class="object-cover rounded-t-xl md:rounded-tr-none md:rounded-l-xl w-full md:w-2/5"
class="w-full h-auto rounded-t-xl md:rounded-tr-none md:rounded-l-xl md:w-2/5"
/>
<div class="p-6">
<h3 class="text-xl font-bold">Modern Downtown Studio</h3>
@@ -454,9 +437,9 @@
<!-- Listing 1 -->
<div class="bg-white rounded-xl shadow-md relative">
<img
src="images/properties/a1.jpg"
src="/images/properties/images[0]"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
@@ -514,7 +497,7 @@
<img
src="images/properties/b1.jpg"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
@@ -572,7 +555,7 @@
<img
src="images/properties/c1.jpg"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
+1 -1
View File
@@ -245,7 +245,7 @@
<a href="/property.html">
<img
class="h-32 w-full rounded-md object-cover"
src="/images/properties/a1.jpg"
src="/images/properties/images[0]"
alt="Property 1"
/>
</a>
+8 -8
View File
@@ -266,9 +266,9 @@
<!-- Listing 1 -->
<div class="rounded-xl shadow-md relative">
<img
src="images/properties/a1.jpg"
src="/images/properties/images[0]"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
@@ -326,7 +326,7 @@
<img
src="images/properties/b1.jpg"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
@@ -384,7 +384,7 @@
<img
src="images/properties/c1.jpg"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
@@ -443,7 +443,7 @@
<img
src="images/properties/d1.jpg"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
@@ -498,9 +498,9 @@
<!-- Listing 5 -->
<div class="rounded-xl shadow-md relative">
<img
src="images/properties/e1.jpg"
src="/images/properties/e1.jpg"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
@@ -558,7 +558,7 @@
<img
src="images/properties/f1.jpg"
alt=""
class="object-cover rounded-t-xl"
class="w-full h-auto rounded-t-xl"
/>
<div class="p-4">
<div class="text-left md:text-center lg:text-left mb-6">
+89 -84
View File
@@ -58,7 +58,7 @@
<a class="flex flex-shrink-0 items-center" href="/index.html">
<img
class="h-10 w-auto"
src="/images/logo-white.png"
src="images/logo-white.png"
alt="PropertyPulse"
/>
@@ -196,26 +196,26 @@
<div class="hidden" id="mobile-menu">
<div class="space-y-1 px-2 pb-3 pt-2">
<a
href="/index.html"
class="bg-black text-white block rounded-md px-3 py-2 text-base font-medium"
>Home</a
>
<a
href="/properties.html"
class="text-white block rounded-md px-3 py-2 text-base font-medium"
>Properties</a
>
<a
href="/add-property.html"
class="text-white block rounded-md px-3 py-2 text-base font-medium"
>Add Property</a
>
<button
class="flex items-center text-white bg-gray-700 hover:bg-gray-900 hover:text-white rounded-md px-3 py-2 my-5"
>
<i class="fa-brands fa-google mr-2"></i>
<span>Login or Register</span>
</button>
href="/index.html"
class="bg-black text-white block rounded-md px-3 py-2 text-base font-medium"
>Home</a
>
<a
href="/properties.html"
class="text-white block rounded-md px-3 py-2 text-base font-medium"
>Properties</a
>
<a
href="/add-property.html"
class="text-white block rounded-md px-3 py-2 text-base font-medium"
>Add Property</a
>
<button
class="flex items-center text-white bg-gray-700 hover:bg-gray-900 hover:text-white rounded-md px-3 py-2 my-5"
>
<i class="fa-brands fa-google mr-2"></i>
<span>Login or Register</span>
</button>
</div>
</div>
</nav>
@@ -270,9 +270,9 @@
<div class="container-xl m-auto">
<div class="grid grid-cols-1">
<img
src="images/properties/a1.jpg"
src="/images/properties/images[0]"
alt=""
class="object-cover h-[400px]"
class="object-cover h-[400px] w-full"
width="1800"
/>
</div>
@@ -288,6 +288,7 @@
>
<i class="fas fa-arrow-left mr-2"></i> Back to Properties
</a>
</div>
</section>
<!-- Property Info -->
@@ -443,73 +444,73 @@
<div class="bg-white p-6 rounded-lg shadow-md">
<h3 class="text-xl font-bold mb-6">Contact Property Manager</h3>
<form>
<div class='mb-4'>
<div class="mb-4">
<label
class='block text-gray-700 text-sm font-bold mb-2'
htmlFor='name'
class="block text-gray-700 text-sm font-bold mb-2"
htmlFor="name"
>
Name:
</label>
<input
class='shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline'
id='name'
name='name'
type='text'
placeholder='Enter your name'
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="name"
name="name"
type="text"
placeholder="Enter your name"
required
/>
</div>
<div class='mb-4'>
<div class="mb-4">
<label
class='block text-gray-700 text-sm font-bold mb-2'
htmlFor='email'
class="block text-gray-700 text-sm font-bold mb-2"
htmlFor="email"
>
Email:
</label>
<input
class='shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline'
id='email'
name='email'
type='email'
placeholder='Enter your email'
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="email"
name="email"
type="email"
placeholder="Enter your email"
required
/>
</div>
<div class='mb-4'>
<div class="mb-4">
<label
class='block text-gray-700 text-sm font-bold mb-2'
htmlFor='phone'
class="block text-gray-700 text-sm font-bold mb-2"
htmlFor="phone"
>
Phone:
</label>
<input
class='shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline'
id='phone'
name='phone'
type='text'
placeholder='Enter your phone number'
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="phone"
name="phone"
type="text"
placeholder="Enter your phone number"
/>
</div>
<div class='mb-4'>
<div class="mb-4">
<label
class='block text-gray-700 text-sm font-bold mb-2'
htmlFor='message'
class="block text-gray-700 text-sm font-bold mb-2"
htmlFor="message"
>
Message:
</label>
<textarea
class='shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 h-44 focus:outline-none focus:shadow-outline'
id='message'
name='message'
placeholder='Enter your message'
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 h-44 focus:outline-none focus:shadow-outline"
id="message"
name="message"
placeholder="Enter your message"
></textarea>
</div>
<div>
<button
class='bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-full w-full focus:outline-none focus:shadow-outline flex items-center justify-center'
type='submit'
class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-full w-full focus:outline-none focus:shadow-outline flex items-center justify-center"
type="submit"
>
<FaPaperPlane class='mr-2' /> Send Message
<i class="fas fa-paper-plane mr-2"></i> Send Message
</button>
</div>
</form>
@@ -520,34 +521,38 @@
</section>
<!-- Images -->
<section class='bg-blue-50 p-4'>
<div class='container mx-auto'>
<div class='grid grid-cols-2 gap-4'>
<div class='col-span-2'>
<img
src='./images/properties/a1.jpg'
alt=''
class='object-cover h-[400px] w-full rounded-xl cursor-pointer' />
</div>
<div class='col-span-2'>
<img
src='./images/properties/a2.jpg'
alt=''
class='object-cover h-[400px] w-full rounded-xl cursor-pointer' />
</div>
<div class='col-span-2'>
<img
src='./images/properties/a3.jpg'
alt=''
class='object-cover h-[400px] w-full rounded-xl cursor-pointer' />
</div>
<div class='col-span-2'>
<img
src='./images/properties/a4.jpg'
alt=''
class='object-cover h-[400px] w-full rounded-xl cursor-pointer' />
</div>
<section class="bg-blue-50 p-4">
<div class="container mx-auto">
<div class="grid grid-cols-2 gap-4">
<div class="col-span-2">
<img
src="/images/properties/images[0]"
alt=""
class="object-cover h-[400px] w-full rounded-xl cursor-pointer"
/>
</div>
<div class="col-span-2">
<img
src="./images/properties/a2.jpg"
alt=""
class="object-cover h-[400px] w-full rounded-xl cursor-pointer"
/>
</div>
<div class="col-span-2">
<img
src="./images/properties/a3.jpg"
alt=""
class="object-cover h-[400px] w-full rounded-xl cursor-pointer"
/>
</div>
<div class="col-span-2">
<img
src="./images/properties/a4.jpg"
alt=""
class="object-cover h-[400px] w-full rounded-xl cursor-pointer"
/>
</div>
</div>
</div>
</section>
+2 -2
View File
@@ -228,7 +228,7 @@
<i class="fas fa-trash text-red-600"></i>
</button>
<img
src="images/properties/a1.jpg"
src="/images/properties/images[0]"
alt=""
class="object-cover rounded-t-xl"
/>
@@ -292,7 +292,7 @@
<i class="fas fa-trash text-red-600"></i>
</button>
<img
src="images/properties/b1.jpg"
src="/images/properties/images[0]"
alt=""
class="object-cover rounded-t-xl"
/>
+4 -2
View File
@@ -25,7 +25,8 @@ const PropertyPage = async ({ params }) => {
return (
<>
<PropertyHeaderImage image={property.images[0]} />
<PropertyHeaderImage image="/images/properties/images[0]"
/>
<section>
<div className='container m-auto py-6 px-6'>
<Link
@@ -50,7 +51,8 @@ const PropertyPage = async ({ params }) => {
</div>
</div>
</section>
<PropertyImages images={property.images} />
<PropertyImages images="/images/properties/images[0]"
/>
</>
);
};
+1 -1
View File
@@ -32,7 +32,7 @@ const SearchResultsPage = async ({
}
const propertiesQueryResults = await Property.find(query).lean();
const properties = convertToSerializeableObject(propertiesQueryResults);
const properties = propertiesQueryResults.map(convertToSerializeableObject);
return (
<>
Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

+1 -1
View File
@@ -24,7 +24,7 @@ const FeaturedPropertyCard = ({ property }) => {
return (
<div className='bg-white rounded-xl shadow-md relative flex flex-col md:flex-row'>
<Image
src={property.images[0]}
src="/images/properties/images[0]"
alt=''
width={0}
height={0}
+1 -1
View File
@@ -33,7 +33,7 @@ const ProfileProperties = ({ properties: initialProperties }) => {
<Link href={`/properties/${property._id}`}>
<Image
className='h-32 w-full rounded-md object-cover'
src={property.images[0]}
src="/images/properties/images[0]"
alt=''
width={500}
height={100}
+1 -1
View File
@@ -23,7 +23,7 @@ const PropertyCard = ({ property }) => {
return (
<div className='rounded-xl shadow-md relative'>
<Image
src={property.images[0]}
src={property.images}
alt=''
height={0}
width={0}
+2 -15
View File
@@ -1,23 +1,10 @@
'use client';
import { useEffect } from 'react';
import { useFormState, useFormStatus } from 'react-dom';
import { useFormState } from 'react-dom';
import { useSession } from 'next-auth/react';
import { toast } from 'react-toastify';
import addMessage from '@/app/actions/addMessage';
import { FaPaperPlane } from 'react-icons/fa';
const SubmitMessageButton = () => {
const status = useFormStatus();
return (
<button
className='bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-full w-full focus:outline-none focus:shadow-outline flex items-center justify-center'
type='submit'
>
<FaPaperPlane className='mr-2' />{' '}
{status.pending ? 'Sending...' : 'Send Message'}
</button>
);
};
import SubmitMessageButton from './SubmitMessageButton';
const PropertyContactForm = ({ property }) => {
const { data: session } = useSession();
+18
View File
@@ -0,0 +1,18 @@
import { useFormStatus } from 'react-dom';
import { FaPaperPlane } from 'react-icons/fa';
const SubmitMessageButton = () => {
const { pending } = useFormStatus();
return (
<button
className='bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-full w-full focus:outline-none focus:shadow-outline flex items-center justify-center'
type='submit'
disabled={pending}
>
<FaPaperPlane className='mr-2' />{' '}
{pending ? 'Sending...' : 'Send Message'}
</button>
);
};
export default SubmitMessageButton;
+7 -2
View File
@@ -1357,6 +1357,7 @@
"resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.5.1.tgz",
"integrity": "sha512-sf4N18vl5FHS8lPRWZjTZShgIziDqSxan3MazHClvYYXezsAPn6hApRvAS2HEMTq7MXzRcvvt4sYgQWLubwnBw==",
"license": "SEE LICENSE IN LICENSE.txt",
"peer": true,
"workspaces": [
"src/style-spec"
],
@@ -1887,6 +1888,7 @@
"resolved": "https://registry.npmjs.org/photoswipe/-/photoswipe-5.4.4.tgz",
"integrity": "sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.12.0"
}
@@ -1950,6 +1952,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.1",
@@ -2098,6 +2101,7 @@
"resolved": "https://registry.npmjs.org/preact/-/preact-10.22.1.tgz",
"integrity": "sha512-jRYbDDgMpIb5LHq3hkI0bbl+l/TQ9UnkdQ0ww+lp+4MMOdqaUYdFc5qeyP+IV8FAd/2Em7drVPeKdQxsiWCf/A==",
"license": "MIT",
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
@@ -2191,6 +2195,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -2203,6 +2208,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -2230,8 +2236,7 @@
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/react-map-gl": {
"version": "7.1.7",
+11 -1
View File
@@ -1,5 +1,6 @@
[
{
"_id": "1",
"owner": "1",
"name": "Boston Commons Retreat",
"type": "Apartment",
@@ -38,12 +39,13 @@
"email": "john@gmail.com",
"phone": "617-555-5555"
},
"images": ["a1.jpg", "a2.jpg", "a3.jpg"],
"images": ["a4.jpg", "a2.jpg", "a3.jpg"],
"is_featured": false,
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
},
{
"_id": "2",
"owner": "1",
"name": "Cozy Downtown Loft",
"type": "Apartment",
@@ -87,6 +89,7 @@
"updatedAt": "2024-01-02T00:00:00.000Z"
},
{
"_id": "3",
"owner": "2",
"name": "Luxury Condo with a View",
"type": "Condo",
@@ -132,6 +135,7 @@
"updatedAt": "2024-01-03T00:00:00.000Z"
},
{
"_id": "4",
"owner": "2",
"name": "Charming Cottage Getaway",
"type": "Cottage Or Cabin",
@@ -165,6 +169,7 @@
"updatedAt": "2024-01-04T00:00:00.000Z"
},
{
"_id": "5",
"owner": "3",
"name": "Modern Downtown Studio",
"type": "Studio",
@@ -200,6 +205,7 @@
"updatedAt": "2024-01-05T00:00:00.000Z"
},
{
"_id": "6",
"owner": "3",
"name": "Seaside Retreat",
"type": "House",
@@ -235,6 +241,7 @@
"updatedAt": "2024-01-06T00:00:00.000Z"
},
{
"_id": "7",
"owner": "4",
"name": "Rustic Cabin in the Woods",
"type": "Cottage Or Cabin",
@@ -269,6 +276,7 @@
"updatedAt": "2024-01-07T00:00:00.000Z"
},
{
"_id": "8",
"owner": "5",
"name": "Ski-In/Ski-Out Chalet",
"type": "Chalet",
@@ -303,6 +311,7 @@
"updatedAt": "2024-01-08T00:00:00.000Z"
},
{
"_id": "9",
"owner": "6",
"name": "Mountain View Retreat",
"type": "House",
@@ -338,6 +347,7 @@
"updatedAt": "2024-01-09T00:00:00.000Z"
},
{
"_id": "10",
"owner": "7",
"name": "Historic Downtown Loft",
"type": "Apartment",
+374
View File
@@ -0,0 +1,374 @@
[
{
"owner": "1",
"name": "Boston Commons Retreat",
"type": "Apartment",
"description": "This is 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.",
"location": {
"street": "120 Tremont Street",
"city": "Boston",
"state": "MA",
"zipcode": "02108"
},
"beds": 2,
"baths": 1,
"square_feet": 1500,
"amenities": [
"Wifi",
"Full kitchen",
"Washer & Dryer",
"Free Parking",
"Hot Tub",
"24/7 Security",
"Wheelchair Accessible",
"Elevator Access",
"Dishwasher",
"Gym/Fitness Center",
"Air Conditioning",
"Balcony/Patio",
"Smart TV",
"Coffee Maker"
],
"rates": {
"weekly": 1100,
"monthly": 4200
},
"seller_info": {
"name": "John Doe",
"email": "john@gmail.com",
"phone": "617-555-5555"
},
"images": ["a4.jpg", "a2.jpg", "a3.jpg"],
"is_featured": false,
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
},
{
"owner": "1",
"name": "Cozy Downtown Loft",
"type": "Apartment",
"description": "A cozy downtown loft with great city views.",
"location": {
"street": "45 Main Street",
"city": "New York",
"state": "NY",
"zipcode": "10001"
},
"beds": 1,
"baths": 1,
"square_feet": 1800,
"amenities": [
"Wifi",
"Full kitchen",
"Washer & Dryer",
"Free Parking",
"Hot Tub",
"24/7 Security",
"Wheelchair Accessible",
"Elevator Access",
"Dishwasher",
"High-Speed Internet",
"Air Conditioning",
"Smart TV",
"Outdoor Grill/BBQ"
],
"rates": {
"weekly": 1000,
"monthly": 4000
},
"seller_info": {
"name": "Jane Smith",
"email": "jane@gmail.com",
"phone": "212-555-5555"
},
"images": ["b1.jpg", "b2.jpg", "b3.jpg"],
"is_featured": false,
"createdAt": "2024-01-02T00:00:00.000Z",
"updatedAt": "2024-01-02T00:00:00.000Z"
},
{
"owner": "2",
"name": "Luxury Condo with a View",
"type": "Condo",
"description": "Experience luxury in this stunning condo with breathtaking views.",
"location": {
"street": "500 Lux Lane",
"city": "Los Angeles",
"state": "CA",
"zipcode": "90001"
},
"beds": 3,
"baths": 2,
"square_feet": 2200,
"amenities": [
"Wifi",
"Full kitchen",
"Washer & Dryer",
"Free Parking",
"Hot Tub",
"24/7 Security",
"Wheelchair Accessible",
"Elevator Access",
"Dishwasher",
"Swimming Pool",
"Gym/Fitness Center",
"Air Conditioning",
"Smart TV",
"Coffee Maker"
],
"rates": {
"nightly": 200,
"weekly": 750,
"monthly": 3300
},
"seller_info": {
"name": "David Johnson",
"email": "david@gmail.com",
"phone": "213-555-5555"
},
"images": ["c1.jpg", "c2.jpg", "c3.jpg"],
"is_featured": false,
"createdAt": "2024-01-03T00:00:00.000Z",
"updatedAt": "2024-01-03T00:00:00.000Z"
},
{
"owner": "2",
"name": "Charming Cottage Getaway",
"type": "Cottage Or Cabin",
"description": "Escape to this charming cottage for a peaceful retreat.",
"location": {
"street": "123 Countryside Lane",
"city": "Austin",
"state": "TX",
"zipcode": "78701"
},
"beds": 1,
"baths": 1,
"square_feet": 900,
"amenities": [
"Fireplace",
"Outdoor Grill/BBQ",
"Balcony/Patio",
"Coffee Maker"
],
"rates": {
"weekly": 2000
},
"seller_info": {
"name": "Emily Davis",
"email": "emily@gmail.com",
"phone": "512-555-5555"
},
"images": ["d1.jpg", "d2.jpg", "d3.jpg"],
"is_featured": false,
"createdAt": "2024-01-04T00:00:00.000Z",
"updatedAt": "2024-01-04T00:00:00.000Z"
},
{
"owner": "3",
"name": "Modern Downtown Studio",
"type": "Studio",
"description": "Stay in style in this modern downtown studio apartment.",
"location": {
"street": "75 Urban Avenue",
"city": "Chicago",
"state": "IL",
"zipcode": "60601"
},
"beds": 1,
"baths": 1,
"square_feet": 900,
"amenities": [
"High-Speed Internet",
"Smart TV",
"Air Conditioning",
"Gym/Fitness Center",
"Outdoor Grill/BBQ"
],
"rates": {
"weekly": 1100,
"monthly": 4200
},
"seller_info": {
"name": "Michael Brown",
"email": "michael@gmail.com",
"phone": "312-555-5555"
},
"images": ["e1.jpg", "e2.jpg", "e3.jpg"],
"is_featured": true,
"createdAt": "2024-01-05T00:00:00.000Z",
"updatedAt": "2024-01-05T00:00:00.000Z"
},
{
"owner": "3",
"name": "Seaside Retreat",
"type": "House",
"description": "Escape to this seaside house for a relaxing getaway.",
"location": {
"street": "456 Oceanfront Drive",
"city": "Miami",
"state": "FL",
"zipcode": "33101"
},
"beds": 4,
"baths": 3,
"square_feet": 2800,
"amenities": [
"Beach Access",
"Swimming Pool",
"Balcony/Patio",
"Smart TV",
"Outdoor Grill/BBQ"
],
"rates": {
"nightly": 500,
"weekly": 2500
},
"seller_info": {
"name": "Sarah Wilson",
"email": "sarah@gmail.com",
"phone": "305-555-5555"
},
"images": ["f1.jpg", "f2.jpg", "f3.jpg"],
"is_featured": true,
"createdAt": "2024-01-06T00:00:00.000Z",
"updatedAt": "2024-01-06T00:00:00.000Z"
},
{
"owner": "4",
"name": "Rustic Cabin in the Woods",
"type": "Cottage Or Cabin",
"description": "Experience nature in this cozy rustic cabin.",
"location": {
"street": "789 Forest Lane",
"city": "Denver",
"state": "CO",
"zipcode": "80201"
},
"beds": 2,
"baths": 1,
"square_feet": 1100,
"amenities": [
"Fireplace",
"Outdoor Grill/BBQ",
"Hiking Trails Access",
"Pet-Friendly"
],
"rates": {
"nightly": 475,
"weekly": 2000
},
"seller_info": {
"name": "Robert Anderson",
"email": "robert@gmail.com",
"phone": "303-555-5555"
},
"images": ["g1.jpg", "g2.jpg", "g3.jpg"],
"is_featured": false,
"createdAt": "2024-01-07T00:00:00.000Z",
"updatedAt": "2024-01-07T00:00:00.000Z"
},
{
"owner": "5",
"name": "Ski-In/Ski-Out Chalet",
"type": "Chalet",
"description": "Hit the slopes from this cozy ski-in/ski-out chalet.",
"location": {
"street": "321 Mountain Road",
"city": "Aspen",
"state": "CO",
"zipcode": "81611"
},
"beds": 3,
"baths": 2,
"square_feet": 1800,
"amenities": [
"Ski Equipment Storage",
"Fireplace",
"Balcony/Patio",
"Smart TV"
],
"rates": {
"nightly": 300,
"weekly": 1100
},
"seller_info": {
"name": "Jennifer Martin",
"email": "jennifer@gmail.com",
"phone": "970-555-5555"
},
"images": ["h1.jpg", "h2.jpg", "h3.jpg"],
"is_featured": false,
"createdAt": "2024-01-08T00:00:00.000Z",
"updatedAt": "2024-01-08T00:00:00.000Z"
},
{
"owner": "6",
"name": "Mountain View Retreat",
"type": "House",
"description": "Enjoy stunning mountain views from this spacious retreat.",
"location": {
"street": "600 Summit Drive",
"city": "Boulder",
"state": "CO",
"zipcode": "80301"
},
"beds": 4,
"baths": 3,
"square_feet": 2400,
"amenities": [
"Mountain View",
"Hiking Trails Access",
"Air Conditioning",
"Smart TV",
"Outdoor Grill/BBQ"
],
"rates": {
"weekly": 1000,
"monthly": 3800
},
"seller_info": {
"name": "Lisa Taylor",
"email": "lisa@gmail.com",
"phone": "303-555-5555"
},
"images": ["i1.jpg", "i2.jpg", "i3.jpg"],
"is_featured": false,
"createdAt": "2024-01-09T00:00:00.000Z",
"updatedAt": "2024-01-09T00:00:00.000Z"
},
{
"owner": "7",
"name": "Historic Downtown Loft",
"type": "Apartment",
"description": "Step back in time with a stay in this historic downtown loft.",
"location": {
"street": "123 History Lane",
"city": "Philadelphia",
"state": "PA",
"zipcode": "19101"
},
"beds": 2,
"baths": 1,
"square_feet": 1200,
"amenities": [
"High-Speed Internet",
"Air Conditioning",
"Smart TV",
"Coffee Maker"
],
"rates": {
"weekly": 550,
"monthly": 2100
},
"seller_info": {
"name": "Matthew Harris",
"email": "matthew@gmail.com",
"phone": "215-555-5555"
},
"images": ["j1.jpg", "j2.jpg", "j3.jpg"],
"is_featured": false,
"createdAt": "2024-01-10T00:00:00.000Z",
"updatedAt": "2024-01-10T00:00:00.000Z"
}
]
Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB