From 2de78b7461badf4aa1f7238424e678b9f51964d6 Mon Sep 17 00:00:00 2001 From: ale Date: Mon, 8 Dec 2025 23:08:24 +0100 Subject: [PATCH] share link Signed-off-by: ale --- app/page.tsx | 120 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index c8c7704..622afad 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,7 +1,8 @@ 'use client'; -import { useState, useEffect } from 'react'; -import { Search, Copy, Check, Hash, Key, AlertCircle, Loader2, Database } from 'lucide-react'; +import { useState, useEffect, useCallback } from 'react'; +import { useSearchParams, useRouter } from 'next/navigation'; +import { Search, Copy, Check, Hash, Key, AlertCircle, Loader2, Database, Link } from 'lucide-react'; interface SearchResult { found: boolean; @@ -46,12 +47,56 @@ function formatNumber(num: number): string { } export default function Home() { + const searchParams = useSearchParams(); + const router = useRouter(); const [query, setQuery] = useState(''); const [result, setResult] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [copiedField, setCopiedField] = useState(null); const [stats, setStats] = useState(null); + const [copiedLink, setCopiedLink] = useState(false); + + const performSearch = useCallback(async (searchQuery: string) => { + if (!searchQuery.trim()) return; + + setLoading(true); + setError(''); + setResult(null); + + try { + const response = await fetch('/api/search', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query: searchQuery.trim() }) + }); + + if (!response.ok) { + throw new Error('Search failed'); + } + + const data = await response.json(); + setResult(data); + + // Update URL with search query + const newUrl = new URL(window.location.href); + newUrl.searchParams.set('q', searchQuery.trim()); + router.replace(newUrl.pathname + newUrl.search, { scroll: false }); + } catch (_err) { + setError('Failed to perform search. Please check your connection.'); + } finally { + setLoading(false); + } + }, [router]); + + // Load query from URL on mount + useEffect(() => { + const urlQuery = searchParams.get('q'); + if (urlQuery) { + setQuery(urlQuery); + performSearch(urlQuery); + } + }, [searchParams, performSearch]); useEffect(() => { const fetchStats = async () => { @@ -73,30 +118,7 @@ export default function Home() { const handleSearch = async (e: React.FormEvent) => { e.preventDefault(); - if (!query.trim()) return; - - setLoading(true); - setError(''); - setResult(null); - - try { - const response = await fetch('/api/search', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ query: query.trim() }) - }); - - if (!response.ok) { - throw new Error('Search failed'); - } - - const data = await response.json(); - setResult(data); - } catch (_err) { - setError('Failed to perform search. Please check your connection.'); - } finally { - setLoading(false); - } + performSearch(query); }; const copyToClipboard = (text: string, field: string) => { @@ -105,6 +127,14 @@ export default function Home() { setTimeout(() => setCopiedField(null), 2000); }; + const copyShareLink = () => { + const url = new URL(window.location.href); + url.searchParams.set('q', query.trim()); + navigator.clipboard.writeText(url.toString()); + setCopiedLink(true); + setTimeout(() => setCopiedLink(false), 2000); + }; + const HashDisplay = ({ label, value, field }: { label: string; value: string; field: string }) => (
@@ -166,19 +196,35 @@ export default function Home() { value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Enter a hash or plaintext..." - className="w-full px-6 py-4 pr-14 text-lg rounded-2xl border-2 border-gray-200 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 outline-none transition-all shadow-sm" + className="w-full px-6 py-4 pr-28 text-lg rounded-2xl border-2 border-gray-200 focus:border-blue-500 focus:ring-4 focus:ring-blue-100 outline-none transition-all shadow-sm" /> - )} - + +