Skip to content

Commit

Permalink
Merge pull request #179 from jaykayudo/feat/hotel-search-feat
Browse files Browse the repository at this point in the history
Implement Hotel Search Results UI Page
  • Loading branch information
JosueBrenes authored Mar 4, 2025
2 parents 79d3fe6 + 7964f3c commit b53690c
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 2 deletions.
62 changes: 61 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@
"@creit.tech/stellar-wallets-kit": "^1.4.1",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-popover": "^1.1.6",
"@radix-ui/react-select": "^2.1.6",
"@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slot": "^1.1.2",
"@stellar/freighter-api": "^3.1.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"leaflet": "^1.9.4",
"lucide-react": "^0.475.0",
"next": "15.1.7",
"prettier": "^3.5.1",
"react": "^19.0.0",
"react-day-picker": "^8.10.1",
"react-dom": "^19.0.0",
"react-leaflet": "^5.0.0",
"tailwind-merge": "^3.0.1",
Expand Down
94 changes: 94 additions & 0 deletions src/app/dashboard/hotel/search/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
'use client';
import { Card, CardContent, CardHeader } from '@/components/ui/card';
import Header from '@/components/layouts/Header';
import React from 'react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import DatePicker from '@/components/hotels/search/datepicker';
import Link from 'next/link';
import { Heart, LocateIcon, MapPin } from 'lucide-react';

export default function HotelSearch() {
const searchData = [
{
image: "/img/room1.png",
name: "Shikara Hotel",
location: "329 calle santos, paseo collos, San Jose",
price: "40.14"
},
{
image: "/img/room1.png",
name: "Shikara Hotel",
location: "329 calle santos, paseo collos, San Jose",
price: "40.14"
},
{
image: "/img/room1.png",
name: "Shikara Hotel",
location: "329 calle santos, paseo collos, San Jose",
price: "40.14"
},
{
image: "/img/room1.png",
name: "Shikara Hotel",
location: "329 calle santos, paseo collos, San Jose",
price: "40.14"
},
{
image: "/img/room1.png",
name: "Shikara Hotel",
location: "329 calle santos, paseo collos, San Jose",
price: "40.14"
},
]
return (
<div className='mt-[20px]'>
<Header />
<h1 className="text-2xl font-bold">Find hotel to stay</h1>
<div className="flex justify-between items-center mt-6">
<div className='flex justify-between items-center gap-[10px]' >
<div>
<label className='block mb-3'>
Date
</label>
<DatePicker />
</div>
<div>
<label className='block mb-3'>
Where to
</label>
<Input placeholder="San José, San Pedro" className="w-full" />
</div>

</div>

<Button>Search</Button>
</div>
<div className='flex justify-end'>
<Link href={"#"} className='text-sky-600'>
View all
</Link>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 mt-8">
{searchData.map((data, idx)=>(
<Card key={idx}>
<img
src={data.image}
alt={data.name}
className="w-full h-48 object-cover rounded-t-md"
/>
<CardContent className="p-4">
<h3 className="text-lg font-semibold flex justify-between py-2">{data.name} <button><Heart className='text-rose-400'/></button></h3>
<p className="text-sm text-gray-600 flex gap-[5px]"> <MapPin className='text-sky-700' size={20}/> {data.location}</p>
<p className="mt-2 text-primary font-bold py-2">${data.price} <span className='text-xs italic text-gray-400'>/night</span></p>

</CardContent>
</Card>
))}

</div>
</div>
);
}

3 changes: 2 additions & 1 deletion src/app/dashboard/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { Header } from "@/components/layouts/Header";
// Define public routes that don't require authentication
const PUBLIC_ROUTES = [
"/dashboard/hotel/payment",
"/dashboard/hotel/details"
"/dashboard/hotel/details",
"/dashboard/hotel/search",
];

const Layout = ({ children }: { children: React.ReactNode }) => {
Expand Down
11 changes: 11 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

@layer base {}

@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
45 changes: 45 additions & 0 deletions src/components/hotels/search/datepicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"use client"

import * as React from "react"
import { format } from "date-fns"
import { Calendar as CalendarIcon } from "lucide-react"

import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Calendar } from "@/components/ui/calendar"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"

const DatePicker = () =>{
const [date, setDate] = React.useState<Date>()

return (
<Popover>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"w-full justify-start text-left font-normal",
!date && "text-muted-foreground"
)}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{date ? format(date, "PPP") : <span>Pick a date</span>}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
initialFocus
/>
</PopoverContent>
</Popover>
)
}

export default DatePicker;
76 changes: 76 additions & 0 deletions src/components/ui/calendar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"use client"

import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"

import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"

export type CalendarProps = React.ComponentProps<typeof DayPicker>

function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: CalendarProps) {
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn("p-3", className)}
classNames={{
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
month: "space-y-4",
caption: "flex justify-center pt-1 relative items-center",
caption_label: "text-sm font-medium",
nav: "space-x-1 flex items-center",
nav_button: cn(
buttonVariants({ variant: "outline" }),
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
),
nav_button_previous: "absolute left-1",
nav_button_next: "absolute right-1",
table: "w-full border-collapse space-y-1",
head_row: "flex",
head_cell:
"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
row: "flex w-full mt-2",
cell: cn(
"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md",
props.mode === "range"
? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
: "[&:has([aria-selected])]:rounded-md"
),
day: cn(
buttonVariants({ variant: "ghost" }),
"h-8 w-8 p-0 font-normal aria-selected:opacity-100"
),
day_range_start: "day-range-start",
day_range_end: "day-range-end",
day_selected:
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
day_today: "bg-accent text-accent-foreground",
day_outside:
"day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground",
day_disabled: "text-muted-foreground opacity-50",
day_range_middle:
"aria-selected:bg-accent aria-selected:text-accent-foreground",
day_hidden: "invisible",
...classNames,
}}
components={{
IconLeft: ({ className, ...props }) => (
<ChevronLeft className={cn("h-4 w-4", className)} {...props} />
),
IconRight: ({ className, ...props }) => (
<ChevronRight className={cn("h-4 w-4", className)} {...props} />
),
}}
{...props}
/>
)
}
Calendar.displayName = "Calendar"

export { Calendar }
Loading

0 comments on commit b53690c

Please sign in to comment.