first commit

Made-with: Cursor
This commit is contained in:
Michilis
2026-04-01 02:46:53 +00:00
commit 76210db03d
126 changed files with 20208 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
"use client";
import { useState } from "react";
import { api } from "@/lib/api";
import { Search, RefreshCw, Bug } from "lucide-react";
export default function NostrToolsPage() {
const [fetchInput, setFetchInput] = useState("");
const [fetchResult, setFetchResult] = useState<any>(null);
const [fetching, setFetching] = useState(false);
const [cacheStatus, setCacheStatus] = useState("");
const [refreshing, setRefreshing] = useState(false);
const [debugInput, setDebugInput] = useState("");
const [debugResult, setDebugResult] = useState<any>(null);
const [debugging, setDebugging] = useState(false);
const [error, setError] = useState("");
const handleFetch = async () => {
if (!fetchInput.trim()) return;
setFetching(true);
setError("");
setFetchResult(null);
try {
const isNaddr = fetchInput.startsWith("naddr");
const data = await api.fetchNostrEvent(
isNaddr ? { naddr: fetchInput } : { eventId: fetchInput }
);
setFetchResult(data);
} catch (err: any) {
setError(err.message);
} finally {
setFetching(false);
}
};
const handleRefreshCache = async () => {
setRefreshing(true);
setCacheStatus("");
setError("");
try {
const result = await api.refreshCache();
setCacheStatus(result.message || "Cache refreshed successfully.");
} catch (err: any) {
setError(err.message);
} finally {
setRefreshing(false);
}
};
const handleDebug = async () => {
if (!debugInput.trim()) return;
setDebugging(true);
setError("");
setDebugResult(null);
try {
const data = await api.debugEvent(debugInput);
setDebugResult(data);
} catch (err: any) {
setError(err.message);
} finally {
setDebugging(false);
}
};
return (
<div className="space-y-6">
<h1 className="text-2xl font-bold text-on-surface">Nostr Tools</h1>
{error && <p className="text-error text-sm">{error}</p>}
<div className="bg-surface-container-low rounded-xl p-6">
<h2 className="text-lg font-semibold text-on-surface mb-4 flex items-center gap-2">
<Search size={18} />
Manual Fetch
</h2>
<div className="flex gap-3">
<input
placeholder="Event ID or naddr..."
value={fetchInput}
onChange={(e) => setFetchInput(e.target.value)}
className="bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 w-full focus:outline-none focus:ring-1 focus:ring-primary/40 flex-1"
/>
<button
onClick={handleFetch}
disabled={fetching || !fetchInput.trim()}
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-gradient-to-r from-primary to-primary-container text-on-primary font-semibold text-sm hover:opacity-90 transition-opacity disabled:opacity-50 whitespace-nowrap"
>
{fetching ? "Fetching..." : "Fetch"}
</button>
</div>
{fetchResult && (
<pre className="mt-4 bg-surface-container rounded-lg p-4 text-on-surface/80 text-xs overflow-x-auto max-h-96 overflow-y-auto font-mono">
{JSON.stringify(fetchResult, null, 2)}
</pre>
)}
</div>
<div className="bg-surface-container-low rounded-xl p-6">
<h2 className="text-lg font-semibold text-on-surface mb-4 flex items-center gap-2">
<RefreshCw size={18} />
Cache Management
</h2>
<button
onClick={handleRefreshCache}
disabled={refreshing}
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-gradient-to-r from-primary to-primary-container text-on-primary font-semibold text-sm hover:opacity-90 transition-opacity disabled:opacity-50"
>
<RefreshCw size={16} className={refreshing ? "animate-spin" : ""} />
{refreshing ? "Refreshing..." : "Refresh Cache"}
</button>
{cacheStatus && (
<p className="mt-3 text-green-400 text-sm">{cacheStatus}</p>
)}
</div>
<div className="bg-surface-container-low rounded-xl p-6">
<h2 className="text-lg font-semibold text-on-surface mb-4 flex items-center gap-2">
<Bug size={18} />
Debug Event
</h2>
<div className="flex gap-3">
<input
placeholder="Event ID..."
value={debugInput}
onChange={(e) => setDebugInput(e.target.value)}
className="bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 w-full focus:outline-none focus:ring-1 focus:ring-primary/40 flex-1"
/>
<button
onClick={handleDebug}
disabled={debugging || !debugInput.trim()}
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-gradient-to-r from-primary to-primary-container text-on-primary font-semibold text-sm hover:opacity-90 transition-opacity disabled:opacity-50 whitespace-nowrap"
>
{debugging ? "Debugging..." : "Debug"}
</button>
</div>
{debugResult && (
<pre className="mt-4 bg-surface-container rounded-lg p-4 text-on-surface/80 text-xs overflow-x-auto max-h-96 overflow-y-auto font-mono">
{JSON.stringify(debugResult, null, 2)}
</pre>
)}
</div>
</div>
);
}