diff --git a/package-lock.json b/package-lock.json index 0fda084..76205dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,17 +11,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", @@ -2003,6 +2006,42 @@ } } }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.6.tgz", + "integrity": "sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz", @@ -2176,7 +2215,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz", "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==", - "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, @@ -5343,6 +5381,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", @@ -8776,6 +8823,19 @@ "node": ">=0.10.0" } }, + "node_modules/react-day-picker": { + "version": "8.10.1", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz", + "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/gpbl" + }, + "peerDependencies": { + "date-fns": "^2.28.0 || ^3.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", diff --git a/package.json b/package.json index 8d7b9f4..9c9bc5a 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/app/dashboard/hotel/search/page.tsx b/src/app/dashboard/hotel/search/page.tsx new file mode 100644 index 0000000..4b8b45d --- /dev/null +++ b/src/app/dashboard/hotel/search/page.tsx @@ -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 ( +
+
+

Find hotel to stay

+
+
+
+ + +
+
+ + +
+ +
+ + +
+
+ + View all + +
+
+ {searchData.map((data, idx)=>( + + {data.name} + +

{data.name}

+

{data.location}

+

${data.price} /night

+ +
+
+ ))} + +
+
+ ); +} + diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx index b9f5f10..66910b1 100644 --- a/src/app/dashboard/layout.tsx +++ b/src/app/dashboard/layout.tsx @@ -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 }) => { diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 0000000..46896e5 --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,11 @@ + +@layer base {} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/src/components/hotels/search/datepicker.tsx b/src/components/hotels/search/datepicker.tsx new file mode 100644 index 0000000..be7a921 --- /dev/null +++ b/src/components/hotels/search/datepicker.tsx @@ -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() + + return ( + + + + + + + + + ) +} + +export default DatePicker; \ No newline at end of file diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx new file mode 100644 index 0000000..115cff9 --- /dev/null +++ b/src/components/ui/calendar.tsx @@ -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 + +function Calendar({ + className, + classNames, + showOutsideDays = true, + ...props +}: CalendarProps) { + return ( + .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 }) => ( + + ), + IconRight: ({ className, ...props }) => ( + + ), + }} + {...props} + /> + ) +} +Calendar.displayName = "Calendar" + +export { Calendar } diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx new file mode 100644 index 0000000..29c7bd2 --- /dev/null +++ b/src/components/ui/popover.tsx @@ -0,0 +1,33 @@ +"use client" + +import * as React from "react" +import * as PopoverPrimitive from "@radix-ui/react-popover" + +import { cn } from "@/lib/utils" + +const Popover = PopoverPrimitive.Root + +const PopoverTrigger = PopoverPrimitive.Trigger + +const PopoverAnchor = PopoverPrimitive.Anchor + +const PopoverContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( + + + +)) +PopoverContent.displayName = PopoverPrimitive.Content.displayName + +export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }