feat(24-02): render-first root layout, guarded write actions, public setup viewing
- Remove authLoading spinner gate — app renders immediately for all visitors - Expand isPublicRoute to include /, /global-items/*, /setups/*, /users/, /login - Replace hard window.location.href redirect with soft navigate() after auth resolves - Remove onboarding loading spinner — pass isAuthenticated as enabled to guard query - Add AuthPromptModal to root JSX for global availability - Guard Add to Collection and Add to Thread buttons with isAuthenticated check - Rework setup detail page to use usePublicSetup for anonymous visitors - Wrap all write action UI (Add Items, Delete, Public toggle, remove/classify) in isAuthenticated guards
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { createFileRoute, Link } from "@tanstack/react-router";
|
||||
import { useAuth } from "../../hooks/useAuth";
|
||||
import { useFormatters } from "../../hooks/useFormatters";
|
||||
import { useGlobalItem } from "../../hooks/useGlobalItems";
|
||||
import { useUIStore } from "../../stores/uiStore";
|
||||
@@ -11,8 +12,11 @@ function GlobalItemDetail() {
|
||||
const { globalItemId } = Route.useParams();
|
||||
const { data: item, isLoading, error } = useGlobalItem(Number(globalItemId));
|
||||
const { weight, price } = useFormatters();
|
||||
const { data: auth } = useAuth();
|
||||
const isAuthenticated = !!auth?.user;
|
||||
const openAddToCollection = useUIStore((s) => s.openAddToCollection);
|
||||
const openAddToThread = useUIStore((s) => s.openAddToThread);
|
||||
const openAuthPrompt = useUIStore((s) => s.openAuthPrompt);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -133,18 +137,26 @@ function GlobalItemDetail() {
|
||||
<div className="flex gap-3 mb-6">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
openAddToCollection(item.id, `${item.brand} ${item.model}`)
|
||||
}
|
||||
onClick={() => {
|
||||
if (!isAuthenticated) {
|
||||
openAuthPrompt();
|
||||
return;
|
||||
}
|
||||
openAddToCollection(item.id, `${item.brand} ${item.model}`);
|
||||
}}
|
||||
className="bg-gray-700 text-white rounded-lg px-5 py-2.5 text-sm font-medium hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
Add to Collection
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
openAddToThread(item.id, `${item.brand} ${item.model}`)
|
||||
}
|
||||
onClick={() => {
|
||||
if (!isAuthenticated) {
|
||||
openAuthPrompt();
|
||||
return;
|
||||
}
|
||||
openAddToThread(item.id, `${item.brand} ${item.model}`);
|
||||
}}
|
||||
className="bg-white text-gray-700 border border-gray-200 rounded-lg px-5 py-2.5 text-sm font-medium hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
Add to Thread
|
||||
|
||||
Reference in New Issue
Block a user