138 lines
4.3 KiB
TypeScript
138 lines
4.3 KiB
TypeScript
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>
|
||
)
|
||
}
|