HotTRDealsFrontend/src/components/DealDetails/DealDetails.tsx
cureb a48d32fdec created image array
ui overhaul
2026-01-23 17:28:05 +00:00

138 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useMemo } from "react"
import { ExternalLink, Copy } from "lucide-react"
import { Link } from "react-router-dom"
type DealDetailsProps = {
title: string
price: string
store: string
link: string
postedBy: string
postedAgo: string // ISO veya "19 dakika" gibi bir şey gelebilir
}
function formatTimeAgo(input: string) {
if (!input) return ""
// Zaten "dakika/saat/gün" gibi geldiyse elleme
const looksHuman =
/dakika|saat|gün|hafta|ay|yıl|sn|saniye/i.test(input)
if (looksHuman) return input
const date = new Date(input)
if (Number.isNaN(date.getTime())) return input
const diffMs = Date.now() - date.getTime()
const diffSec = Math.max(0, Math.floor(diffMs / 1000))
if (diffSec < 60) return `${diffSec} sn`
const diffMin = Math.floor(diffSec / 60)
if (diffMin < 60) return `${diffMin} dk`
const diffHour = Math.floor(diffMin / 60)
if (diffHour < 24) return `${diffHour} sa`
const diffDay = Math.floor(diffHour / 24)
if (diffDay < 7) return `${diffDay} gün`
const diffWeek = Math.floor(diffDay / 7)
if (diffWeek < 4) return `${diffWeek} hf`
const diffMonth = Math.floor(diffDay / 30)
if (diffMonth < 12) return `${diffMonth} ay`
const diffYear = Math.floor(diffDay / 365)
return `${diffYear} yıl`
}
export default function DealDetails({
title,
price,
store,
link,
postedBy,
postedAgo,
}: DealDetailsProps) {
const hasLink = Boolean(link && link.trim().length > 0)
const timeAgo = useMemo(() => formatTimeAgo(postedAgo), [postedAgo])
return (
<div className="rounded-3xl bg-surface border border-border p-6">
{/* Header */}
<div className="flex items-start justify-between gap-4">
<h1 className="min-w-0 text-2xl font-semibold text-text leading-snug">
{title}
</h1>
{store ? (
<span className="shrink-0 rounded-full px-3 py-1 text-xs font-semibold bg-background border border-border text-primary">
{store}
</span>
) : null}
</div>
{/* Meta: posted by + time */}
<div className="mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-text-muted">
<span>
Paylaşan{" "}
{postedBy ? (
<Link
to={`/user/${postedBy}`}
className="text-text font-semibold hover:underline"
onClick={(e) => e.stopPropagation()}
>
{postedBy}
</Link>
) : (
<span className="text-text font-semibold">-</span>
)}
</span>
<span className="opacity-60"></span>
<span>{timeAgo ? `${timeAgo} önce` : "-"}</span>
</div>
{/* Price */}
<div className="mt-5 flex items-end justify-between gap-4">
<div className="flex flex-col">
<span className="text-s text-text-muted">Fiyat</span>
<span className="mt-1 text-3xl font-extrabold text-primary tracking-tight">
{price}
</span>
</div>
</div>
<div className="mt-5 h-px w-full bg-border/60" />
{/* Actions */}
<div className="mt-5 grid grid-cols-1 sm:grid-cols-2 gap-3">
<a
href={hasLink ? link : undefined}
target="_blank"
rel="noopener noreferrer"
aria-disabled={!hasLink}
onClick={(e) => {
if (!hasLink) e.preventDefault()
}}
className={[
"inline-flex items-center justify-center gap-2 rounded-xl px-4 py-3 text-sm font-semibold transition",
hasLink
? "bg-primary text-[color:var(--color-on-primary)] hover:bg-primary-hover"
: "bg-background border border-border text-text-muted cursor-not-allowed",
].join(" ")}
>
<ExternalLink className="w-4 h-4" />
Fırsata Git
</a>
<button
type="button"
onClick={() => {
const value = hasLink ? link : window.location.href
try {
navigator.clipboard.writeText(value)
} catch {}
}}
className="inline-flex items-center justify-center gap-2 rounded-xl px-4 py-3 text-sm font-semibold transition bg-background border border-border text-text hover:border-border/70"
>
<Copy className="w-4 h-4" />
Linki Kopyala
</button>
</div>
</div>
)
}