diff --git a/src/app/page.tsx b/src/app/page.tsx
index 2b2d483..f17b4ea 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -9,12 +9,13 @@ import Footer from "@/components/landing/footer";
import SearchBy from "@/components/search-results/search";
import Results from "@/components/search-results/results";
import Features from "@/components/details/features";
+import List from "@/components/list-property/list";
export default function Home() {
return (
<>
-
+
>
diff --git a/src/components/list-property/list.tsx b/src/components/list-property/list.tsx
new file mode 100644
index 0000000..cd26c97
--- /dev/null
+++ b/src/components/list-property/list.tsx
@@ -0,0 +1,587 @@
+"use client";
+
+import { useState, useRef } from "react";
+import localFont from "next/font/local";
+import gsap from "gsap";
+import { useGSAP } from "@gsap/react";
+import {
+ House,
+ Buildings,
+ Farm,
+ Bed,
+ MapPin,
+ Camera,
+ WifiHigh,
+ Article,
+ CurrencyDollar,
+ CheckCircle,
+ CalendarBlank,
+ ShieldCheck,
+ CaretLeft,
+ CaretRight
+} from "@phosphor-icons/react";
+
+const figtree = localFont({
+ src: [
+ {
+ path: '../../../public/Fonts/figtree/figtree.ttf',
+ },
+ ],
+})
+
+// Shared styles
+const containerStyle = `flex flex-col gap-6 w-full max-w-xl mx-auto`;
+const titleStyle = `${figtree.className} text-3xl font-bold mb-4`;
+const inputStyle = `${figtree.className} w-full p-4 border-2 border-black text-lg outline-none focus:bg-gray-50 transition-colors`;
+const buttonStyle = `${figtree.className} flex items-center justify-center gap-2 px-8 py-3 border-2 border-black bg-[#E7FE78] text-lg font-medium hover:bg-[#dcfc4e] transition-colors disabled:opacity-50 disabled:cursor-not-allowed`;
+const secondaryButtonStyle = `${figtree.className} flex items-center justify-center gap-2 px-8 py-3 border-2 border-black bg-white text-lg font-medium hover:bg-gray-50 transition-colors`;
+const optionCardStyle = (selected: boolean) =>
+ `flex flex-col items-center justify-center gap-3 p-6 border-2 border-black cursor-pointer transition-all hover:bg-gray-50 ${selected ? 'bg-[#E7FE78]' : 'bg-white'}`;
+
+interface FormData {
+ propertyType?: string;
+ placeType?: string;
+ location?: string;
+ guests?: number;
+ bedrooms?: number;
+ beds?: number;
+ bathrooms?: number;
+ amenities?: string[];
+ description?: string;
+ price?: string;
+ instantBook?: boolean;
+ safety?: string[];
+}
+
+type FormValue = string | number | boolean | string[] | undefined;
+
+interface StepProps {
+ onNext: () => void;
+ onBack: () => void;
+ data: FormData;
+ updateData: (key: keyof FormData, value: FormValue) => void;
+}
+
+/* Property Type */
+const PropertyType = ({ onNext, data, updateData }: StepProps) => {
+ const types = [
+ { id: 'house', label: 'House', icon: House },
+ { id: 'flat', label: 'Flat', icon: Buildings },
+ { id: 'farmhouse', label: 'Farmhouse', icon: Farm },
+ { id: 'guesthouse', label: 'Guesthouse', icon: Bed },
+ ];
+
+ const handleSelect = (id: string) => {
+ updateData('propertyType', id);
+ onNext();
+ };
+
+ return (
+
+
What kind of place will you host?
+
+ {types.map((type) => (
+ handleSelect(type.id)}
+ className={optionCardStyle(data.propertyType === type.id)}
+ >
+
+ {type.label}
+
+ ))}
+
+
+ )
+}
+
+/* Property Place Type */
+const PropertyPlaceType = ({ onNext, onBack, data, updateData }: StepProps) => {
+ const places = [
+ { id: 'entire', label: 'An entire place', description: 'Guests have the whole place to themselves.' },
+ { id: 'room', label: 'A room', description: 'Guests have their own room in a home, plus access to shared spaces.' },
+ { id: 'shared', label: 'A shared room', description: 'Guests sleep in a room or common area that may be shared with others.' },
+ ];
+
+ const handleSelect = (id: string) => {
+ updateData('placeType', id);
+ onNext();
+ };
+
+ return (
+
+
What type of place will guests have?
+
+ {places.map((place) => (
+
handleSelect(place.id)}
+ className={`${optionCardStyle(data.placeType === place.id)} flex-row justify-between text-left items-center w-full`}
+ >
+
+ {place.label}
+ {place.description}
+
+
+ ))}
+
+
+
+ Back
+
+
+
+ )
+}
+
+/* Property Location */
+const PropertyLocation = ({ onNext, onBack, data, updateData }: StepProps) => {
+ return (
+
+
Where's your place located?
+
+
+
+ updateData('location', e.target.value)}
+ />
+
+ {/* Placeholder for map */}
+
+ Map Preview
+
+
+
+
+ Back
+
+ onNext()} className={buttonStyle}>
+ Next
+
+
+
+ )
+}
+
+/* Property Capacity */
+const PropertyCapacity = ({ onNext, onBack, data, updateData }: StepProps) => {
+ const counters: { key: keyof FormData; label: string }[] = [
+ { key: 'guests', label: 'Guests' },
+ { key: 'bedrooms', label: 'Bedrooms' },
+ { key: 'beds', label: 'Beds' },
+ { key: 'bathrooms', label: 'Bathrooms' },
+ ];
+
+ const updateCount = (key: keyof FormData, delta: number) => {
+ const current = (data[key] as number) || 0;
+ updateData(key, Math.max(0, current + delta));
+ };
+
+ return (
+
+
Share some basics about your place
+
+ {counters.map((item) => (
+
+
{item.label}
+
+ updateCount(item.key, -1)}
+ className="w-10 h-10 rounded-full border-2 border-black flex items-center justify-center hover:bg-gray-100"
+ >
+ -
+
+ {data[item.key] || 0}
+ updateCount(item.key, 1)}
+ className="w-10 h-10 rounded-full border-2 border-black flex items-center justify-center hover:bg-gray-100"
+ >
+ +
+
+
+
+ ))}
+
+
+
+ Back
+
+ onNext()} className={buttonStyle}>
+ Next
+
+
+
+ )
+}
+
+/* Property Photos */
+const PropertyPhotos = ({ onNext, onBack }: StepProps) => {
+ return (
+
+
Add some photos of your house
+
+
+
+
Drag your photos here
+
Choose at least 5 photos
+
+
Upload from your device
+
+
+
+ Back
+
+ onNext()} className={buttonStyle}>
+ Next
+
+
+
+ )
+}
+
+/* Property Amenities */
+const PropertyAmenities = ({ onNext, onBack, data, updateData }: StepProps) => {
+ const amenities = [
+ { id: 'wifi', label: 'Wi-Fi', icon: WifiHigh },
+ { id: 'kitchen', label: 'Kitchen', icon: House },
+ { id: 'parking', label: 'Free parking', icon: Farm },
+ { id: 'pool', label: 'Pool', icon: Buildings },
+ ];
+
+ const toggleAmenity = (id: string) => {
+ const current = data.amenities || [];
+ const updated = current.includes(id)
+ ? current.filter((item: string) => item !== id)
+ : [...current, id];
+ updateData('amenities', updated);
+ };
+
+ return (
+
+
What does your place offer?
+
+ {amenities.map((amenity) => (
+
toggleAmenity(amenity.id)}
+ className={`${optionCardStyle((data.amenities || []).includes(amenity.id))} items-start w-full`}
+ >
+
+ {amenity.label}
+
+ ))}
+
+
+
+ Back
+
+ onNext()} className={buttonStyle}>
+ Next
+
+
+
+ )
+}
+
+/* Property Description */
+const PropertyDescription = ({ onNext, onBack, data, updateData }: StepProps) => {
+ return (
+
+
How would you describe your place?
+
+
+
+
+ Back
+
+ onNext()} className={buttonStyle}>
+ Next
+
+
+
+ )
+}
+
+/* Property Price */
+const PropertyPrice = ({ onNext, onBack, data, updateData }: StepProps) => {
+ return (
+
+
Now, set your price
+
+
+
+ updateData('price', e.target.value)}
+ />
+
+
per night
+
+
+
+ Back
+
+ onNext()} className={buttonStyle}>
+ Next
+
+
+
+ )
+}
+
+/* Property Instant Approval */
+const PropertyInstantApproval = ({ onNext, onBack, data, updateData }: StepProps) => {
+ return (
+
+
Decide how you'll confirm reservations
+
+
updateData('instantBook', true)}
+ className={`${optionCardStyle(data.instantBook === true)} w-full`}
+ >
+
+
+
+ Use Instant Book
+ Guests can book automatically.
+
+
+
+
updateData('instantBook', false)}
+ className={`${optionCardStyle(data.instantBook === false)} w-full`}
+ >
+
+
+
+ Approve manually
+ You approve or decline booking requests.
+
+
+
+
+
+
+ Back
+
+ onNext()} className={buttonStyle}>
+ Next
+
+
+
+ )
+}
+
+/* Availability Calendar */
+const AvailabilityCalendar = ({ onNext, onBack }: StepProps) => {
+ return (
+
+
When is your place available?
+
+
+
Calendar Component Placeholder
+
+
+
+ Back
+
+ onNext()} className={buttonStyle}>
+ Next
+
+
+
+ )
+}
+
+/* Safety Details */
+const SafetyDetails = ({ onNext, onBack, data, updateData }: StepProps) => {
+ const safetyItems = [
+ { id: 'camera', label: 'Security camera(s)', icon: Camera },
+ { id: 'weapons', label: 'Weapons', icon: ShieldCheck },
+ { id: 'animals', label: 'Dangerous animals', icon: Farm },
+ ];
+
+ const toggleSafety = (id: string) => {
+ const current = data.safety || [];
+ const updated = current.includes(id)
+ ? current.filter((item: string) => item !== id)
+ : [...current, id];
+ updateData('safety', updated);
+ };
+
+ return (
+
+
Does your place have any of these?
+
+ {safetyItems.map((item) => (
+
toggleSafety(item.id)}
+ className={`${optionCardStyle((data.safety || []).includes(item.id))} flex-row justify-between items-center w-full`}
+ >
+
+
+ {item.label}
+
+
+
+ ))}
+
+
+
+ Back
+
+ { }} className={buttonStyle}>
+ Finish
+
+
+
+ )
+}
+
+function List() {
+ const [step, setStep] = useState(0);
+ const [direction, setDirection] = useState(1); // 1 for next, -1 for back
+ const [formData, setFormData] = useState({});
+ const containerRef = useRef(null);
+ const contentRef = useRef(null);
+
+ const steps = [
+ PropertyType,
+ PropertyPlaceType,
+ PropertyLocation,
+ PropertyCapacity,
+ PropertyPhotos,
+ PropertyAmenities,
+ PropertyDescription,
+ PropertyPrice,
+ PropertyInstantApproval,
+ AvailabilityCalendar,
+ SafetyDetails
+ ];
+
+ const CurrentStepComponent = steps[step];
+
+ const updateData = (key: keyof FormData, value: FormValue) => {
+ setFormData(prev => ({ ...prev, [key]: value }));
+ };
+
+ const handleNext = () => {
+ if (step < steps.length - 1) {
+ setDirection(1);
+ setStep(prev => prev + 1);
+ }
+ };
+
+ const handleBack = () => {
+ if (step > 0) {
+ setDirection(-1);
+ setStep(prev => prev - 1);
+ }
+ };
+
+ useGSAP(() => {
+ if (!contentRef.current) return;
+
+ // Animate the content sliding in
+ gsap.fromTo(contentRef.current,
+ {
+ x: direction * 50,
+ opacity: 0
+ },
+ {
+ x: 0,
+ opacity: 1,
+ duration: 0.4,
+ ease: "power2.out"
+ }
+ );
+ }, [step]);
+
+ return (
+
+ {/* Left Panel - Form */}
+
+ {/* Progress Bar - Top */}
+
+
+
+
+ {step + 1}
+
+
Step {step + 1} of {steps.length}
+
+
Exit
+
+
+
+
+ {/* Content */}
+
+
+
+ {/* Right Panel - Visual */}
+
+ {/* Gradient Background */}
+
+
+
+ {/* Decorative Content */}
+
+
+
+ Open your door to hosting
+
+
+ Earn money, reach millions of travelers, and find your freedom. It's easy to get started.
+
+
+
+
+
+ )
+}
+
+export default List;