2f20b1e5c2
Build & Push Docker Image / build (push) Successful in 2m15s
- tools: add deletedAt/deletedBy, soft delete via DELETE /tools/:id when actor has trash entitlement, else immediate hard delete - trash endpoints: GET /tools/trash, POST /tools/trash (admin bulk), POST /tools/trash/restore, DELETE /tools/trash, POST /tools/trash/empty - trash feature for premium/enterprise; exclude trashed from all public surfaces (browse, categories, features, tags, similar, ratings, costs, analytics, redundancy) - TRASH_RETENTION_DAYS env (0 = keep forever) with hourly purge job - frontend: /trash page (premium+, restore for all, permanent delete + empty for admin), admin Tools tab with multi-select bulk trash, sidebar Trash link, tool-detail delete hint
60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
import { Switch, Route, Router as WouterRouter } from "wouter";
|
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
import { Toaster } from "@/components/ui/toaster";
|
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
|
|
// Pages
|
|
import Home from "@/pages/home";
|
|
import ToolsBrowse from "@/pages/tools-browse";
|
|
import ToolDetail from "@/pages/tool-detail";
|
|
import ToolNew from "@/pages/tool-new";
|
|
import ToolEdit from "@/pages/tool-edit";
|
|
import Analytics from "@/pages/analytics";
|
|
import Admin from "@/pages/admin";
|
|
import Redundancy from "@/pages/redundancy";
|
|
import Trash from "@/pages/trash";
|
|
import Login from "@/pages/login";
|
|
import NotFound from "@/pages/not-found";
|
|
|
|
const queryClient = new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
refetchOnWindowFocus: false,
|
|
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
},
|
|
},
|
|
});
|
|
|
|
function Router() {
|
|
return (
|
|
<Switch>
|
|
<Route path="/" component={Home} />
|
|
<Route path="/login" component={Login} />
|
|
<Route path="/tools" component={ToolsBrowse} />
|
|
<Route path="/tools/new" component={ToolNew} />
|
|
<Route path="/tools/:id/edit" component={ToolEdit} />
|
|
<Route path="/tools/:id" component={ToolDetail} />
|
|
<Route path="/analytics" component={Analytics} />
|
|
<Route path="/admin" component={Admin} />
|
|
<Route path="/admin/redundancy" component={Redundancy} />
|
|
<Route path="/trash" component={Trash} />
|
|
<Route component={NotFound} />
|
|
</Switch>
|
|
);
|
|
}
|
|
|
|
function App() {
|
|
return (
|
|
<QueryClientProvider client={queryClient}>
|
|
<TooltipProvider>
|
|
<WouterRouter base={import.meta.env.BASE_URL.replace(/\/$/, "")}>
|
|
<Router />
|
|
</WouterRouter>
|
|
<Toaster />
|
|
</TooltipProvider>
|
|
</QueryClientProvider>
|
|
);
|
|
}
|
|
|
|
export default App;
|