feat: wire frontend pages to tRPC APIs

- Add hooks (useAuth, useSubscription, useNotifications) for real API data
- Add auth service (login/signup) with password hashing and session support
- Replace stub auth with real tRPC calls in login/signup/onboarding pages
- Replace mock dashboard data with real API data from hooks
- Create service pages: DarkWatch, VoicePrint, SpamShield, HomeTitle, RemoveBrokers, Settings
- Update Navbar, TopBar, Sidebar with real user data and correct routes
- Add passwordHash field to users schema for credential auth
- Fix tests to work with real hooks (mock tRPC/hooks)
This commit is contained in:
2026-05-25 17:34:48 -04:00
parent eb8e57c674
commit 7cbcde6a6b
46 changed files with 2418 additions and 418 deletions

View File

@@ -0,0 +1,104 @@
import { createSignal, createResource, For, Show } from "solid-js";
import { Title } from "@solidjs/meta";
import { Sidebar, TopBar } from "~/components/dashboard";
import { Button, Card } from "~/components/ui";
import { api } from "~/lib/api";
export default function RemoveBrokersPage() {
const [sidebarOpen, setSidebarOpen] = createSignal(false);
const [brokers] = createResource(
() => api.removebrokers.getBrokerRegistry.query(),
{ initialValue: [] },
);
const [removalRequests, { refetch }] = createResource(
() => api.removebrokers.getRemovalRequests.query({ page: 1, limit: 20 }),
);
const [stats] = createResource(
() => api.removebrokers.getStats.query(),
);
async function createRequest(brokerId: string) {
await api.removebrokers.createRemovalRequest.mutate({
brokerId,
personalInfo: { name: "", email: "", phone: "", address: "" },
});
refetch();
}
return (
<div class="flex h-[calc(100vh-4rem)] bg-[var(--color-bg)]">
<Title>RemoveBrokers ShieldAI</Title>
<Sidebar open={sidebarOpen()} onClose={() => setSidebarOpen(false)} />
<div class="flex-1 flex flex-col min-w-0">
<TopBar onMenuToggle={() => setSidebarOpen(v => !v)} />
<main class="flex-1 overflow-y-auto p-6">
<div class="max-w-4xl mx-auto">
<h1 class="text-2xl font-bold text-[var(--color-text-primary)] mb-6">RemoveBrokers</h1>
<Show when={stats()}>
<div class="grid grid-cols-3 gap-4 mb-6">
<Card class="p-4 text-center">
<p class="text-2xl font-bold text-[var(--color-brand-primary)]">
{String((stats() as Record<string, unknown>)?.totalRequests ?? 0)}
</p>
<p class="text-xs text-[var(--color-text-tertiary)]">Total Requests</p>
</Card>
<Card class="p-4 text-center">
<p class="text-2xl font-bold text-[var(--color-success)]">
{String((stats() as Record<string, unknown>)?.completedRequests ?? 0)}
</p>
<p class="text-xs text-[var(--color-text-tertiary)]">Completed</p>
</Card>
<Card class="p-4 text-center">
<p class="text-2xl font-bold text-[var(--color-warning)]">
{String((stats() as Record<string, unknown>)?.pendingRequests ?? 0)}
</p>
<p class="text-xs text-[var(--color-text-tertiary)]">Pending</p>
</Card>
</div>
</Show>
<Card class="mb-6">
<div class="px-4 py-3 border-b border-[var(--color-border)]/50">
<h2 class="text-sm font-semibold text-[var(--color-text-primary)]">Data Brokers</h2>
</div>
<div class="divide-y divide-[var(--color-border)]/50">
<For each={brokers()}>
{(broker: Record<string, unknown>) => (
<div class="px-4 py-3 flex items-center justify-between">
<p class="text-sm text-[var(--color-text-primary)]">{String(broker.name ?? "")}</p>
<Button size="sm" onClick={() => createRequest(String(broker.id))}>
Opt Out
</Button>
</div>
)}
</For>
</div>
</Card>
<Card>
<div class="px-4 py-3 border-b border-[var(--color-border)]/50">
<h2 class="text-sm font-semibold text-[var(--color-text-primary)]">Removal Requests</h2>
</div>
<div class="divide-y divide-[var(--color-border)]/50">
<For each={removalRequests()?.items ?? []}>
{(req: Record<string, unknown>) => (
<div class="px-4 py-3">
<p class="text-sm text-[var(--color-text-primary)]">{String(req.brokerName ?? "")}</p>
<p class="text-xs text-[var(--color-text-tertiary)]">Status: {String(req.status ?? "")}</p>
</div>
)}
</For>
<Show when={!(removalRequests()?.items?.length)}>
<div class="px-4 py-8 text-center text-sm text-[var(--color-text-tertiary)]">
No removal requests yet
</div>
</Show>
</div>
</Card>
</div>
</main>
</div>
</div>
);
}