diff --git a/apps/web/app/(dashboard)/_components/app-sidebar.tsx b/apps/web/app/(dashboard)/_components/app-sidebar.tsx index 7657d039..257bb518 100644 --- a/apps/web/app/(dashboard)/_components/app-sidebar.tsx +++ b/apps/web/app/(dashboard)/_components/app-sidebar.tsx @@ -132,6 +132,7 @@ export function AppSidebar() { key={ws.id} onClick={() => { if (ws.id !== workspace?.id) { + router.push("/issues"); switchWorkspace(ws.id); } }} diff --git a/apps/web/features/issues/components/issue-detail.tsx b/apps/web/features/issues/components/issue-detail.tsx index b3a2d0fd..43c38885 100644 --- a/apps/web/features/issues/components/issue-detail.tsx +++ b/apps/web/features/issues/components/issue-detail.tsx @@ -204,12 +204,22 @@ export function IssueDetail({ issueId, onDelete, defaultSidebarOpen = true, layo const issue = useIssueStore((s) => s.issues.find((i) => i.id === id)) ?? null; const [issueLoading, setIssueLoading] = useState(!issue); - // If issue isn't in the store yet, fetch and upsert it + // If issue isn't in the store yet, fetch and upsert it. + // loadedIdRef tracks which issue was already loaded — if it disappears + // from the store (workspace switch clears all issues), skip refetch. + const loadedIdRef = useRef(null); useEffect(() => { if (issue) { + loadedIdRef.current = id; setIssueLoading(false); return; } + // Issue was loaded for this id but vanished → store cleared (workspace switch) + if (loadedIdRef.current === id) { + loadedIdRef.current = null; + return; + } + // Issue not in store → fetch it setIssueLoading(true); api .getIssue(id) diff --git a/apps/web/features/modals/create-workspace.tsx b/apps/web/features/modals/create-workspace.tsx index 29c54856..6400b1dd 100644 --- a/apps/web/features/modals/create-workspace.tsx +++ b/apps/web/features/modals/create-workspace.tsx @@ -1,6 +1,7 @@ "use client"; import { useState } from "react"; +import { useRouter } from "next/navigation"; import { toast } from "sonner"; import { ArrowLeft } from "lucide-react"; import { Input } from "@/components/ui/input"; @@ -18,6 +19,7 @@ import { useWorkspaceStore } from "@/features/workspace"; const SLUG_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/; export function CreateWorkspaceModal({ onClose }: { onClose: () => void }) { + const router = useRouter(); const [name, setName] = useState(""); const [slug, setSlug] = useState(""); const [creating, setCreating] = useState(false); @@ -50,6 +52,7 @@ export function CreateWorkspaceModal({ onClose }: { onClose: () => void }) { slug: slug.trim(), }); onClose(); + router.push("/issues"); await switchWorkspace(ws.id); } catch { toast.error("Failed to create workspace"); diff --git a/apps/web/shared/api/client.ts b/apps/web/shared/api/client.ts index 4721ccf3..f7323a16 100644 --- a/apps/web/shared/api/client.ts +++ b/apps/web/shared/api/client.ts @@ -114,7 +114,8 @@ export class ApiClient { if (!res.ok) { if (res.status === 401) this.handleUnauthorized(); const message = await this.parseErrorMessage(res, `API error: ${res.status} ${res.statusText}`); - this.logger.error(`← ${res.status} ${path}`, { rid, duration: `${Date.now() - start}ms`, error: message }); + const logLevel = res.status === 404 ? "warn" : "error"; + this.logger[logLevel](`← ${res.status} ${path}`, { rid, duration: `${Date.now() - start}ms`, error: message }); throw new Error(message); }