mirror of
https://github.com/anotherhadi/iknowyou.git
synced 2026-04-12 00:47:26 +02:00
init
This commit is contained in:
98
front/src/components/HomePage.svelte
Normal file
98
front/src/components/HomePage.svelte
Normal file
@@ -0,0 +1,98 @@
|
||||
<script>
|
||||
import { RotateCw, AlertTriangle } from "@lucide/svelte";
|
||||
import SearchBar from "./SearchBar.svelte";
|
||||
import SearchList from "./SearchList.svelte";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
let searches = $state([]);
|
||||
let loadError = $state("");
|
||||
let redirecting = $state(false);
|
||||
let redirectTarget = $state("");
|
||||
let demo = $state(false);
|
||||
|
||||
onMount(async () => {
|
||||
loadSearches();
|
||||
fetch("/api/config")
|
||||
.then((r) => r.ok ? r.json() : null)
|
||||
.then((d) => { if (d) demo = d.demo === true; })
|
||||
.catch(() => {});
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const target = params.get("target");
|
||||
const type = params.get("type");
|
||||
if (target && type) {
|
||||
// Clean URL before launching so a refresh doesn't re-trigger
|
||||
window.history.replaceState({}, "", window.location.pathname);
|
||||
await handleSearch(target, type, params.get("profile") || "default");
|
||||
}
|
||||
});
|
||||
|
||||
async function loadSearches() {
|
||||
try {
|
||||
const res = await fetch("/api/searches");
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
const data = await res.json();
|
||||
searches = (data ?? []).sort(
|
||||
(a, b) => new Date(b.started_at) - new Date(a.started_at)
|
||||
);
|
||||
} catch (e) {
|
||||
loadError = e.message;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSearch(target, inputType, profile) {
|
||||
redirectTarget = target;
|
||||
redirecting = true;
|
||||
try {
|
||||
const res = await fetch("/api/searches", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ target, input_type: inputType, profile: profile || undefined }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const body = await res.json().catch(() => ({}));
|
||||
throw new Error(body.error || `HTTP ${res.status}`);
|
||||
}
|
||||
const s = await res.json();
|
||||
window.location.href = `/search/${s.id}`;
|
||||
} catch (e) {
|
||||
redirecting = false;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete(id) {
|
||||
await fetch(`/api/searches/${id}`, { method: "DELETE" });
|
||||
searches = searches.filter((s) => s.id !== id);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-8">
|
||||
|
||||
<div class="card bg-base-200 shadow p-6">
|
||||
{#if redirecting}
|
||||
<div class="flex flex-col items-center justify-center gap-3 py-4">
|
||||
<span class="loading loading-dots loading-md text-primary"></span>
|
||||
<p class="text-sm text-base-content/60">
|
||||
Searching <span class="font-mono text-base-content/90">{redirectTarget}</span>...
|
||||
</p>
|
||||
</div>
|
||||
{:else}
|
||||
<SearchBar onSearch={handleSearch} {demo} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xs uppercase tracking-widest text-base-content/50">Recent searches</h2>
|
||||
<button class="btn btn-ghost btn-xs" onclick={loadSearches}><RotateCw class="size-3" /> refresh</button>
|
||||
</div>
|
||||
|
||||
{#if loadError}
|
||||
<div class="alert alert-error text-sm gap-2"><AlertTriangle size={15} class="shrink-0" />{loadError}</div>
|
||||
{:else}
|
||||
<SearchList {searches} onDelete={handleDelete} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user