sina_sajjadi
2 months ago
34 changed files with 632 additions and 295 deletions
-
22package-lock.json
-
3package.json
-
2src/app/(account-pages)/my-trips/page.tsx
-
2src/app/(account-pages)/passengers-list/page.tsx
-
10src/app/(client-components)/(Header)/LangDropdown.tsx
-
39src/app/(client-components)/(Header)/MainNav1.tsx
-
64src/app/(client-components)/(Header)/SearchDropdown.tsx
-
4src/app/(client-components)/(HeroSearchForm2Mobile)/(stay-search-form)/StaySearchForm.tsx
-
21src/app/(client-components)/(HeroSearchForm2Mobile)/HeroSearchForm2Mobile.tsx
-
47src/app/(client-components)/(HeroSearchForm2Mobile)/LocationInput.tsx
-
2src/app/add-listing/[[...stepIndex]]/PageAddListing1.tsx
-
2src/app/custom-history/page.tsx
-
7src/app/custom-trip/page.tsx
-
4src/app/faq/table.tsx
-
39src/app/forgot-password/page.tsx
-
58src/app/login/page.tsx
-
5src/app/signup/methodes/page.tsx
-
73src/app/signup/otp-code/page.tsx
-
20src/app/signup/page.tsx
-
138src/app/tours/Card.tsx
-
160src/app/tours/SectionGridFilterCard.tsx
-
6src/app/tours/TabFilters.tsx
-
37src/app/tours/[slug]/page.tsx
-
14src/components/FooterNav.tsx
-
75src/components/SearchCard.tsx
-
5src/components/StayCard2.tsx
-
5src/components/contexts/tourDetails.tsx
-
5src/components/contexts/userContext.tsx
-
1src/data/navigation.ts
-
23src/hooks/FormValidation.ts
-
7src/images/Group.svg
-
3src/images/Vector.svg
-
9src/shared/Navigation/NavMobile.tsx
-
15yarn.lock
@ -0,0 +1,138 @@ |
|||
import React, { FC } from "react"; |
|||
import { DEMO_STAY_LISTINGS } from "@/data/listings"; |
|||
import { StayDataType } from "@/data/types"; |
|||
import StartRating from "@/components/StartRating"; |
|||
import BtnLikeIcon from "@/components/BtnLikeIcon"; |
|||
import SaleOffBadge from "@/components/SaleOffBadge"; |
|||
import Badge from "@/shared/Badge"; |
|||
import Link from "next/link"; |
|||
import Image from "next/image"; |
|||
import calender from "../../images/Group.svg"; |
|||
|
|||
export interface StayCard2Props { |
|||
className?: string; |
|||
data?: StayDataType; |
|||
size?: "default" | "small"; |
|||
} |
|||
|
|||
const DEMO_DATA = DEMO_STAY_LISTINGS[0]; |
|||
|
|||
const StayCard2: FC<StayCard2Props> = ({ |
|||
size = "default", |
|||
className = "", |
|||
data = DEMO_DATA, |
|||
}) => { |
|||
const { |
|||
galleryImgs, |
|||
listingCategory, |
|||
address, |
|||
title, |
|||
bedrooms, |
|||
href, |
|||
like, |
|||
saleOff, |
|||
isAds, |
|||
price, |
|||
reviewStart, |
|||
reviewCount, |
|||
id, |
|||
} = data; |
|||
|
|||
// Function to format the dates
|
|||
const formatDate = (dateStr: string) => { |
|||
const date = new Date(dateStr); |
|||
return date.toLocaleDateString("en-GB", { |
|||
day: "2-digit", |
|||
month: "short", |
|||
year: "numeric", |
|||
}); |
|||
}; |
|||
|
|||
// Function to calculate the number of days between two dates
|
|||
const calculateDuration = (start: string, end: string) => { |
|||
const startDate = new Date(start); |
|||
const endDate = new Date(end); |
|||
const timeDiff = endDate.getTime() - startDate.getTime(); |
|||
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)); // Convert ms to days
|
|||
return daysDiff; |
|||
}; |
|||
|
|||
const renderSliderGallery = () => { |
|||
return ( |
|||
<> |
|||
<Link |
|||
href={`/tours/${data?.slug}-${data?.id}`} |
|||
className="relative w-full" |
|||
> |
|||
<div className="h-40 lg:h-56 sm:h-40 overflow-hidden rounded-xl"> |
|||
<Image |
|||
className="w-full h-full object-cover" |
|||
src={data?.image?.image_url?.md || "/default-image.jpg"} |
|||
alt={title || "Stay Image"} |
|||
width={500} |
|||
height={300} |
|||
/> |
|||
</div> |
|||
</Link> |
|||
{ |
|||
<Badge |
|||
className="opacity-70 absolute left-3 top-3" |
|||
name={data.status} |
|||
color={data.status} |
|||
/> |
|||
} |
|||
</> |
|||
); |
|||
}; |
|||
console.log(data); |
|||
|
|||
const renderContent = () => { |
|||
const formattedStartDate = formatDate(data.started_at); |
|||
const formattedEndDate = formatDate(data.ended_at); |
|||
const tripDuration = calculateDuration(data.started_at, data.ended_at); |
|||
|
|||
return ( |
|||
<div className={size === "default" ? "mt-3 space-y-3" : "mt-2 space-y-2"}> |
|||
<div className="space-y-2"> |
|||
<div className="flex items-center space-x-2"> |
|||
<h2 |
|||
className={`font-semibold capitalize text-neutral-900 dark:text-white ${ |
|||
size === "default" ? "text-base" : "text-base" |
|||
}`}
|
|||
> |
|||
<span className="line-clamp-1">{title}</span> |
|||
</h2> |
|||
</div> |
|||
<div className="flex items-center text-neutral-500 dark:text-neutral-400 text-sm space-x-1.5"> |
|||
<Image alt="calendar" src={calender} /> |
|||
<span className=""> |
|||
{formattedStartDate} - {formattedEndDate} |
|||
</span> |
|||
</div> |
|||
<p className="flex items-center text-neutral-500 dark:text-neutral-400 text-sm space-x-1.5"> |
|||
({tripDuration} Days) |
|||
</p> |
|||
</div> |
|||
<div className="w-14 border-b border-neutral-100 dark:border-neutral-800"></div> |
|||
<div className="flex justify-between items-center"> |
|||
<span className="text-base font-semibold"> |
|||
{price} |
|||
{` `} |
|||
</span> |
|||
{!!reviewStart && ( |
|||
<StartRating reviewCount={reviewCount} point={reviewStart} /> |
|||
)} |
|||
</div> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
return ( |
|||
<div className={`nc-StayCard2 group relative ${className}`}> |
|||
{renderSliderGallery()} |
|||
<Link href={`/tours/${data?.slug}-${data?.id}`}>{renderContent()}</Link> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
export default StayCard2; |
@ -0,0 +1,75 @@ |
|||
import { useEffect, useState } from "react"; |
|||
import { useToursContext } from "./contexts/tourDetails"; |
|||
import Image from "next/image"; |
|||
import axiosInstance from "./api/axios"; |
|||
import calender from "./../images/Group.svg"; |
|||
|
|||
function SearchCard({ data }) { |
|||
const { details } = useToursContext(); |
|||
|
|||
const [tourDetail, setTourDetail] = useState(); |
|||
|
|||
console.log(data.image.image_url.sm); |
|||
|
|||
useEffect(() => { |
|||
axiosInstance |
|||
.get(`/api/tours/${data.id}/`) |
|||
.then((response) => { |
|||
setTourDetail(response.data); |
|||
}) |
|||
.catch((error) => { |
|||
console.log(error); |
|||
}); |
|||
}, [data]); |
|||
const formatDate = (dateStr: string) => { |
|||
const date = new Date(dateStr); |
|||
return date.toLocaleDateString("en-GB", { |
|||
day: "2-digit", |
|||
month: "short", |
|||
year: "numeric", |
|||
}); |
|||
}; |
|||
|
|||
// Function to calculate the number of days between two dates
|
|||
const calculateDuration = (start: string, end: string) => { |
|||
const startDate = new Date(start); |
|||
const endDate = new Date(end); |
|||
const timeDiff = endDate.getTime() - startDate.getTime(); |
|||
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)); // Convert ms to days
|
|||
return daysDiff; |
|||
}; |
|||
|
|||
const formattedStartDate = formatDate(data.started_at); |
|||
const formattedEndDate = formatDate(data.ended_at); |
|||
const tripDuration = calculateDuration(data.started_at, data.ended_at); |
|||
|
|||
if (tourDetail) { |
|||
return ( |
|||
<div className="flex hover:bg-neutral-100 p-4 cursor-pointer rounded-3xl"> |
|||
<div className="h-30 inset-0 w-30 h-30 overflow-hidden rounded-xl relative"> |
|||
<Image |
|||
className="max-h-16 object-cover" |
|||
width={100} |
|||
height={100} |
|||
alt={data.title} |
|||
src={data.image.image_url.sm} |
|||
/> |
|||
</div> |
|||
<div className="ml-4"> |
|||
<h3 className="text-amber-800">{data?.title}</h3> |
|||
<div className="flex items-center text-neutral-500 dark:text-neutral-400 text-sm space-x-1.5"> |
|||
<Image alt="calendar" src={calender} /> |
|||
<span className=""> |
|||
{formattedStartDate} - {formattedEndDate} |
|||
</span> |
|||
</div> |
|||
<p className="flex items-center text-neutral-500 dark:text-neutral-400 text-sm space-x-1.5"> |
|||
({tripDuration} Days) |
|||
</p> |
|||
</div> |
|||
</div> |
|||
); |
|||
} |
|||
} |
|||
|
|||
export default SearchCard; |
@ -0,0 +1,7 @@ |
|||
<svg width="13" height="12" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg"> |
|||
<path d="M12.0489 4.11768V10.571C12.0489 11.0599 11.6578 11.4999 11.12 11.4999H1.92889C1.44 11.4999 1 11.1088 1 10.571V4.11768H12.0489Z" stroke="#D09460" stroke-width="0.75" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> |
|||
<path d="M12.0489 2.40667V4.11779H1.04889V2.40667C1.04889 1.91778 1.44 1.47778 1.97778 1.47778H11.1689C11.6089 1.52667 12.0489 1.91778 12.0489 2.40667Z" stroke="#D09460" stroke-width="0.75" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> |
|||
<path d="M4.42223 7.78448H3.34668C3.15112 7.78448 3.00446 7.63781 3.00446 7.44225V6.31781C3.00446 6.12225 3.15112 5.97559 3.34668 5.97559H4.47112C4.66668 5.97559 4.81335 6.12225 4.81335 6.31781V7.44225C4.81335 7.63781 4.61779 7.78448 4.42223 7.78448Z" stroke="#D09460" stroke-width="0.75" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> |
|||
<path d="M3.88446 2.26V0.5" stroke="#D09460" stroke-width="0.75" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> |
|||
<path d="M9.16443 0.5V2.26" stroke="#D09460" stroke-width="0.75" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> |
|||
</svg> |
@ -0,0 +1,3 @@ |
|||
<svg width="13" height="9" viewBox="0 0 13 9" fill="none" xmlns="http://www.w3.org/2000/svg"> |
|||
<path d="M12.0489 1.11768V7.57102C12.0489 8.05991 11.6578 8.49991 11.12 8.49991H1.92889C1.44 8.49991 1 8.1088 1 7.57102V1.11768H12.0489Z" stroke="#D09460" stroke-width="0.75" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> |
|||
</svg> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue