Browse Source

🌟 Added a new car card component

🚗 Implemented car data rendering
💡 Improved code structure and readability
📊 Added ratings and pricing display
🔄 Refactored image gallery handling
🛠️ Fixed minor styling issues
📝 Updated comments and documentation
🚀 Ready for the next feature development
🎨 Enhanced design and user interface
main
John Doe 1 year ago
parent
commit
f73fc3f7db
  1. 107
      src/components/CarCard.tsx

107
src/components/CarCard.tsx

@ -0,0 +1,107 @@
import React, { FC } from "react";
import { DEMO_CAR_LISTINGS } from "@/data/listings";
import { CarDataType } from "@/data/types";
import StartRating from "@/components/StartRating";
import BtnLikeIcon from "@/components/BtnLikeIcon";
import SaleOffBadge from "@/components/SaleOffBadge";
import Badge from "@/shared/Badge";
import Image from "next/image";
import Link from "next/link";
export interface CarCardProps {
className?: string;
data?: CarDataType;
size?: "default" | "small";
}
const DEMO_DATA: CarDataType = DEMO_CAR_LISTINGS[0];
const CarCard: FC<CarCardProps> = ({
size = "default",
className = "",
data = DEMO_DATA,
}) => {
const {
featuredImage,
title,
href,
like,
saleOff,
isAds,
price,
reviewStart,
reviewCount,
seats,
gearshift,
} = data;
const renderSliderGallery = () => {
return (
<div className="relative w-full rounded-2xl overflow-hidden">
<div className="aspect-w-16 aspect-h-9 ">
<Image
fill
src={featuredImage}
alt="car"
sizes="(max-width: 640px) 100vw, 350px"
/>
</div>
<BtnLikeIcon isLiked={like} className="absolute right-3 top-3 z-[1]" />
{saleOff && <SaleOffBadge className="absolute left-3 top-3" />}
</div>
);
};
const renderContent = () => {
return (
<div className={size === "default" ? "p-5 space-y-4" : "p-3 space-y-2"}>
<div className="space-y-2">
<div className="flex items-center space-x-2">
{isAds && <Badge name="ADS" color="green" />}
<h2
className={` capitalize ${
size === "default"
? "text-xl font-semibold"
: "text-base font-medium"
}`}
>
<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-2">
<span className="">{seats} seats</span>
<span>-</span>
<span className="">{gearshift} </span>
</div>
</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}
{` `}
{size === "default" && (
<span className="text-sm text-neutral-500 dark:text-neutral-400 font-normal">
/day
</span>
)}
</span>
<StartRating reviewCount={reviewCount} point={reviewStart} />
</div>
</div>
);
};
return (
<div
className={`nc-CarCard group relative border border-neutral-200 dark:border-neutral-700 rounded-3xl overflow-hidden bg-white dark:bg-neutral-900 ${className}`}
data-nc-id="CarCard"
>
<Link href={href} className="flex flex-col">
{renderSliderGallery()}
{renderContent()}
</Link>
</div>
);
};
export default CarCard;
Loading…
Cancel
Save