152 lines
7.4 KiB
TypeScript
152 lines
7.4 KiB
TypeScript
'use client';
|
|
|
|
import { useMemo, useState } from 'react';
|
|
import { X } from 'lucide-react';
|
|
import { formatPrice, isAvailableFor, MOCK_TLDS, normalizeSld } from './domain-search-data';
|
|
|
|
export default function DomainSearchResults({
|
|
isFa,
|
|
base,
|
|
}: {
|
|
isFa: boolean;
|
|
base: string;
|
|
}) {
|
|
const [openMore, setOpenMore] = useState(false);
|
|
const searchedBase = useMemo(() => normalizeSld(base), [base]);
|
|
|
|
if (!searchedBase) return null;
|
|
|
|
return (
|
|
<>
|
|
<section className="max-w-7xl mx-auto px-6 lg:px-10 pt-10">
|
|
<div className={`flex items-center justify-between gap-3 ${isFa ? 'flex-row-reverse' : ''}`}>
|
|
<div className={`text-sm font-extrabold text-[color:var(--text-primary)] ${isFa ? 'text-right' : 'text-left'}`}>
|
|
{isFa ? `نتایج جستجو برای ${searchedBase}` : `Search results for ${searchedBase}`}
|
|
</div>
|
|
<button
|
|
type="button"
|
|
onClick={() => setOpenMore(true)}
|
|
className="text-xs font-semibold text-[#80c8f5] hover:opacity-90 transition-opacity light:text-sky-600"
|
|
>
|
|
{isFa ? 'مشاهده بیشتر' : 'See more'}
|
|
</button>
|
|
</div>
|
|
|
|
<div className="mt-4 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
|
|
{MOCK_TLDS.map((tld) => {
|
|
const domain = `${searchedBase}${tld.tld}`;
|
|
const available = isAvailableFor(searchedBase, tld.tld);
|
|
const price = formatPrice(isFa, tld);
|
|
return (
|
|
<div
|
|
key={tld.tld}
|
|
className="rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] backdrop-blur-xl p-4 light:shadow-[0_18px_70px_rgba(2,6,23,0.06)]"
|
|
>
|
|
<div className={`flex items-start justify-between gap-3 ${isFa ? 'flex-row-reverse' : ''}`}>
|
|
<div className="min-w-0">
|
|
<div className={`text-sm font-extrabold text-[color:var(--text-primary)] ${isFa ? 'text-right' : 'text-left'}`}>
|
|
{domain}
|
|
</div>
|
|
<div className={`mt-1 text-xs text-[color:var(--text-muted-3)] ${isFa ? 'text-right' : 'text-left'}`}>
|
|
{price} {isFa ? 'تومان/سال' : 'Toman/yr'}
|
|
</div>
|
|
</div>
|
|
<span
|
|
className={[
|
|
'shrink-0 px-3 py-1 rounded-full text-xs font-semibold border',
|
|
available
|
|
? 'border-emerald-400/30 bg-emerald-400/10 text-emerald-200 light:text-[#0a192f]'
|
|
: 'border-rose-400/30 bg-rose-400/10 text-rose-200 light:text-[#0a192f]',
|
|
].join(' ')}
|
|
>
|
|
{available ? (isFa ? 'موجود' : 'Available') : isFa ? 'گرفته شده' : 'Taken'}
|
|
</span>
|
|
</div>
|
|
|
|
<button
|
|
type="button"
|
|
disabled={!available}
|
|
className={[
|
|
'mt-3 w-full px-4 py-2 rounded-xl text-xs font-extrabold transition-opacity',
|
|
available
|
|
? 'text-[#0a192f] bg-gradient-to-l from-[#84e1bc] to-[#80c8f5] hover:opacity-90'
|
|
: 'text-[color:var(--text-muted-2)] bg-[color:var(--glass-02)] border border-[color:var(--border-10)] cursor-not-allowed',
|
|
].join(' ')}
|
|
>
|
|
{available ? (isFa ? 'خرید' : 'Buy') : isFa ? 'گرفته شده' : 'Taken'}
|
|
</button>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</section>
|
|
|
|
{/* Modal: all TLDs */}
|
|
{openMore ? (
|
|
<div className="fixed inset-0 z-[999]">
|
|
<button
|
|
type="button"
|
|
onClick={() => setOpenMore(false)}
|
|
className="absolute inset-0 bg-black/60 light:bg-black/25 backdrop-blur-[2px]"
|
|
aria-label={isFa ? 'بستن' : 'Close'}
|
|
/>
|
|
|
|
<div className="absolute left-1/2 top-1/2 w-[92vw] max-w-3xl -translate-x-1/2 -translate-y-1/2 rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--global-surface-bg-80)] backdrop-blur-xl shadow-[0_20px_90px_rgba(0,0,0,0.35)] overflow-hidden">
|
|
<div className={`flex items-center justify-between gap-3 px-5 py-4 border-b border-[color:var(--border-10)] ${isFa ? 'flex-row-reverse' : ''}`}>
|
|
<div className="text-sm font-extrabold text-[color:var(--text-primary)]">
|
|
{isFa ? 'لیست پسوندها و قیمتها' : 'TLDs & pricing'}
|
|
</div>
|
|
<button
|
|
type="button"
|
|
onClick={() => setOpenMore(false)}
|
|
className="w-10 h-10 rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-02)] flex items-center justify-center hover:bg-[color:var(--glass-05)] transition-colors"
|
|
>
|
|
<X className="w-5 h-5 text-[color:var(--text-muted)]" />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="p-5">
|
|
<div className="overflow-auto rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-02)]">
|
|
<table className="w-full text-sm light:[&_th]:text-[color:var(--text-primary)] light:[&_td]:text-[color:var(--text-muted)]">
|
|
<thead className="bg-[color:var(--glass-05)]">
|
|
<tr className={`${isFa ? 'text-right' : 'text-left'}`}>
|
|
<th className="px-4 py-3 font-bold text-slate-100/90">{isFa ? 'پسوند' : 'TLD'}</th>
|
|
<th className="px-4 py-3 font-bold text-slate-100/90">{isFa ? 'قیمت سالانه' : 'Yearly price'}</th>
|
|
<th className="px-4 py-3 font-bold text-slate-100/90">{isFa ? 'وضعیت' : 'Status'}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y divide-[color:var(--border-10)]">
|
|
{MOCK_TLDS.map((tld) => {
|
|
const available = isAvailableFor(searchedBase, tld.tld);
|
|
return (
|
|
<tr key={tld.tld} className={`${isFa ? 'text-right' : 'text-left'}`}>
|
|
<td className="px-4 py-3 text-[color:var(--text-primary)] font-semibold">{tld.tld}</td>
|
|
<td className="px-4 py-3 text-[color:var(--text-muted)]">
|
|
{formatPrice(isFa, tld)} {isFa ? 'تومان/سال' : 'Toman/yr'}
|
|
</td>
|
|
<td className="px-4 py-3">
|
|
<span
|
|
className={[
|
|
'px-3 py-1 rounded-full text-xs font-semibold border inline-flex',
|
|
available
|
|
? 'border-emerald-400/30 bg-emerald-400/10 text-emerald-200 light:text-[#0a192f]'
|
|
: 'border-rose-400/30 bg-rose-400/10 text-rose-200 light:text-[#0a192f]',
|
|
].join(' ')}
|
|
>
|
|
{available ? (isFa ? 'موجود' : 'Available') : isFa ? 'گرفته شده' : 'Taken'}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : null}
|
|
</>
|
|
);
|
|
}
|