Polish Foundry desktop UI: billing redesign, sidebar hover menu, org switching fix

- Redesign billing page with task-hours pricing model (Free: 8h, Pro: 200h/seat)
- Add bulk hour purchase packages and Stripe payment management
- Remove Usage nav section, add upgrade CTA in Members for free plan
- Fix gear icon to open menu on hover with debounced timers
- Fix org switching in workspace flyout (portal outside-click detection)
- Fix tab strip padding when sidebar is collapsed
- Update website components and Tauri config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Nicholas Kissel 2026-03-11 19:34:25 -07:00
parent f6656a90af
commit ed6e6f6fa5
24 changed files with 1746 additions and 1028 deletions

View file

@ -4,6 +4,7 @@ import type { FoundryBillingPlanId } from "@sandbox-agent/foundry-shared";
import { Navigate, Outlet, createRootRoute, createRoute, createRouter, useRouterState } from "@tanstack/react-router";
import { MockLayout } from "../components/mock-layout";
import {
MockAccountSettingsPage,
MockHostedCheckoutPage,
MockOrganizationBillingPage,
MockOrganizationSelectorPage,
@ -30,6 +31,12 @@ const signInRoute = createRoute({
component: SignInRoute,
});
const accountRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/account",
component: AccountRoute,
});
const organizationsRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/organizations",
@ -84,6 +91,7 @@ const repoRoute = createRoute({
const routeTree = rootRoute.addChildren([
indexRoute,
signInRoute,
accountRoute,
organizationsRoute,
organizationSettingsRoute,
organizationBillingRoute,
@ -152,6 +160,18 @@ function SignInRoute() {
return <MockSignInPage />;
}
function AccountRoute() {
const snapshot = useMockAppSnapshot();
if (!isMockFrontendClient && isAppSnapshotBootstrapping(snapshot)) {
return <AppLoadingScreen label="Loading account..." />;
}
if (snapshot.auth.status === "signed_out") {
return <Navigate to="/signin" replace />;
}
return <MockAccountSettingsPage />;
}
function OrganizationsRoute() {
const snapshot = useMockAppSnapshot();
if (!isMockFrontendClient && isAppSnapshotBootstrapping(snapshot)) {