hilingriviw/src/components/Card/UserLocationDetailRatingsCard/index.tsx
2026-06-03 13:48:23 +03:00

84 lines
3.1 KiB
TypeScript

import { CleanlinessIcon } from '../../Icons/CleanlinessIcon';
import { FacilityIcon } from '../../Icons/FacilityIcon';
import { AccessIcon } from '../../Icons/AccessIcon';
import { ServiceIcon } from '../../Icons/ServiceIcon';
interface RatingData {
score: number;
count: number;
}
interface DetailRatings {
environment: number;
cleanliness: number;
price: number;
facility: number;
}
interface UserLocationDetailRatingsCardProps<T> {
data: T;
getCriticData: (data: T) => RatingData;
getUserData: (data: T) => RatingData;
getCriticDetails?: (data: T) => DetailRatings;
getUserDetails?: (data: T) => DetailRatings;
}
const UserLocationDetailRatingsCard = <T,>({
data,
getUserData,
getUserDetails
}: UserLocationDetailRatingsCardProps<T>) => {
const userData = getUserData(data);
const userDetails = getUserDetails?.(data);
const formatCount = (count: number): string | number => {
return count >= 1000
? `${(count / 1000).toFixed(1).replace(/\.0$/, '')}k`
: count;
};
const calculateScore = (score: number, count: number): string | number => {
return count !== 0 ? Math.floor(score / count) : "NR";
};
const detailItems = userDetails ? [
{ label: 'Akses', value: userDetails.environment, icon: <AccessIcon className="w-7 h-7" strokeWidth={1.1} /> },
{ label: 'Pelayanan', value: userDetails.price, icon: <ServiceIcon className="w-7 h-7" strokeWidth={1.1} /> },
{ label: 'Kebersihan', value: userDetails.cleanliness, icon: <CleanlinessIcon className="w-7 h-7" strokeWidth={1.1} /> },
{ label: 'Fasilitas', value: userDetails.facility, icon: <FacilityIcon className="w-7 h-7" strokeWidth={1.1} /> },
] : [];
return (
<div className="w-full justify-center mt-2 flex flex-row gap-2 overflow-x-auto [&::-webkit-scrollbar]:hidden">
{/* USER SCORE card */}
<div className="bg-secondary rounded-xl px-4 py-3 flex items-center gap-4 flex-shrink-0 min-w-[240px]">
<div>
<div className="text-base font-bold tracking-wide">USER SCORE</div>
{userData.count !== 0 && (
<div className="text-tertiary mt-0.5 text-sm">Based on {formatCount(userData.count)} reviews</div>
)}
</div>
<div className="w-11 h-11 rounded-full ml-7 bg-primary flex items-center justify-center text-lg font-bold flex-shrink-0">
{calculateScore(userData.score, userData.count)}
</div>
</div>
{/* Detail rating cards — all in one row */}
{detailItems.map((item) => (
<div key={item.label} className="border border-gray-600 rounded-xl px-4 py-3 flex items-center gap-3 flex-shrink-0 min-w-[240px]">
<div className="text-tertiary flex-shrink-0">{item.icon}</div>
<div>
<div className="text-tertiary text-sm">{item.label}</div>
<div className="text-2xl font-bold leading-none my-0.5">{item.value}</div>
<div className="text-tertiary text-sm">Based on {formatCount(userData.count)} reviews</div>
</div>
</div>
))}
</div>
);
};
export default UserLocationDetailRatingsCard;