mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
refactor(navigation): name the full-document loads the client router cannot serve
Nine places assigned window.location.href directly: OAuth connects and sign-in hand-offs that land on API routes answering with a redirect, and the reload after account deletion. The newer Next lint rule reads each as an in-app page change. They now go through one helper that says why a document load is the right tool there.
This commit is contained in:
1 parent
c2005fd8f1
commit
48bfc1f987
8 files changed
+29
-9
No files matched your search
@@ -25,6 +25,7 @@ import { isDashboardSnapshotEnabled } from "@/lib/dashboard/snapshot-flag";
|
||||
import { prefetchDashboardSnapshot } from "@/lib/queries/use-dashboard-snapshot";
|
||||
import { clearOfflineCachesForSessionEnd } from "@/lib/pwa/query-persister";
|
||||
import { sanitizeSameOriginPath } from "@/lib/url-safety";
|
||||
import { loadDocument } from "@/lib/navigation/load-document";
|
||||
|
||||
export default function LoginPage() {
|
||||
const router = useRouter();
|
||||
@@ -97,7 +98,7 @@ export default function LoginPage() {
|
||||
|
||||
function handleOidcLogin() {
|
||||
const params = new URLSearchParams({ next: getRedirectTarget() });
|
||||
window.location.href = `/api/auth/oidc/login?${params}`;
|
||||
loadDocument(`/api/auth/oidc/login?${params}`);
|
||||
}
|
||||
|
||||
function getRedirectTarget(): string {
|
||||
@@ -126,7 +127,7 @@ export default function LoginPage() {
|
||||
// page always requires a fresh interactive login here (no ambient one-click
|
||||
// pass), which is exactly what the completion route's freshness rule needs.
|
||||
if (isNativeHandoff) {
|
||||
window.location.href = "/api/auth/native/complete";
|
||||
loadDocument("/api/auth/native/complete");
|
||||
return;
|
||||
}
|
||||
// Start the new session from an empty in-memory cache. The root
|
||||
|
||||
@@ -21,6 +21,7 @@ import { SettingsCard } from "@/components/settings/settings-card";
|
||||
import { SettingsCardHeader } from "@/components/settings/_card-header";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
import { apiFetchRaw } from "@/lib/api/api-fetch";
|
||||
import { loadDocument } from "@/lib/navigation/load-document";
|
||||
|
||||
/**
|
||||
* Settings → Advanced.
|
||||
@@ -225,7 +226,7 @@ function AccountDeleteCard() {
|
||||
// Leave `deleting` set so the confirm button keeps its pending
|
||||
// state through the redirect — the row is gone, nothing to undo.
|
||||
setTimeout(() => {
|
||||
window.location.href = "/auth/login";
|
||||
loadDocument("/auth/login");
|
||||
}, 1_500);
|
||||
} catch {
|
||||
setMsg(t("settings.deleteAccountFailed"));
|
||||
|
||||
@@ -70,6 +70,7 @@ import {
|
||||
IntegrationRedirectGuide,
|
||||
} from "./setup-guide-link";
|
||||
import type { IntegrationCallbackUrls } from "@/lib/integrations/callback-urls";
|
||||
import { loadDocument } from "@/lib/navigation/load-document";
|
||||
|
||||
export function FitbitCard({
|
||||
viewModel,
|
||||
@@ -511,7 +512,7 @@ export function FitbitCard({
|
||||
className="min-h-11 w-full sm:w-auto"
|
||||
data-testid="fitbit-connect"
|
||||
onClick={() => {
|
||||
window.location.href = "/api/fitbit/connect";
|
||||
loadDocument("/api/fitbit/connect");
|
||||
}}
|
||||
>
|
||||
<Link2 className="h-3.5 w-3.5" />
|
||||
|
||||
@@ -85,6 +85,7 @@ import {
|
||||
IntegrationCardDescription,
|
||||
} from "./setup-guide-link";
|
||||
import type { IntegrationCallbackUrls } from "@/lib/integrations/callback-urls";
|
||||
import { loadDocument } from "@/lib/navigation/load-document";
|
||||
|
||||
export function GoogleHealthCard({
|
||||
viewModel,
|
||||
@@ -443,7 +444,7 @@ export function GoogleHealthCard({
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
window.location.href = "/api/google-health/connect";
|
||||
loadDocument("/api/google-health/connect");
|
||||
}}
|
||||
data-testid="google-health-reconnect-button"
|
||||
className="min-h-11"
|
||||
@@ -749,7 +750,7 @@ export function GoogleHealthCard({
|
||||
className="min-h-11 w-full sm:w-auto"
|
||||
data-testid="googlehealth-connect"
|
||||
onClick={() => {
|
||||
window.location.href = "/api/google-health/connect";
|
||||
loadDocument("/api/google-health/connect");
|
||||
}}
|
||||
>
|
||||
<Link2 className="h-3.5 w-3.5" />
|
||||
|
||||
@@ -72,6 +72,7 @@ import {
|
||||
type IntegrationDocsProvider,
|
||||
} from "./setup-guide-link";
|
||||
import type { IntegrationCallbackUrls } from "@/lib/integrations/callback-urls";
|
||||
import { loadDocument } from "@/lib/navigation/load-document";
|
||||
|
||||
export interface OAuthProviderStatus {
|
||||
connected: boolean;
|
||||
@@ -265,7 +266,7 @@ export function OAuthProviderCard({
|
||||
function handleConnect() {
|
||||
setMsg(null);
|
||||
void invalidateKeys(queryClient, measurementDependentKeys);
|
||||
window.location.href = `/api/${provider}/connect`;
|
||||
loadDocument(`/api/${provider}/connect`);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -61,6 +61,7 @@ import {
|
||||
IntegrationRedirectGuide,
|
||||
} from "./setup-guide-link";
|
||||
import type { IntegrationCallbackUrls } from "@/lib/integrations/callback-urls";
|
||||
import { loadDocument } from "@/lib/navigation/load-document";
|
||||
|
||||
export function WhoopCard({
|
||||
viewModel,
|
||||
@@ -493,7 +494,7 @@ export function WhoopCard({
|
||||
className="min-h-11 w-full sm:w-auto"
|
||||
data-testid="whoop-connect"
|
||||
onClick={() => {
|
||||
window.location.href = "/api/whoop/connect";
|
||||
loadDocument("/api/whoop/connect");
|
||||
}}
|
||||
>
|
||||
<Link2 className="h-3.5 w-3.5" />
|
||||
|
||||
@@ -60,6 +60,7 @@ import {
|
||||
IntegrationRedirectGuide,
|
||||
} from "./setup-guide-link";
|
||||
import type { IntegrationCallbackUrls } from "@/lib/integrations/callback-urls";
|
||||
import { loadDocument } from "@/lib/navigation/load-document";
|
||||
|
||||
export function WithingsCard({
|
||||
viewModel,
|
||||
@@ -542,7 +543,7 @@ export function WithingsCard({
|
||||
className="min-h-11 w-full sm:w-auto"
|
||||
data-testid="withings-connect"
|
||||
onClick={() => {
|
||||
window.location.href = "/api/withings/connect";
|
||||
loadDocument("/api/withings/connect");
|
||||
}}
|
||||
>
|
||||
<Link2 className="h-3.5 w-3.5" />
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Leave the client router and load `path` as a new document.
|
||||
*
|
||||
* For destinations the client router cannot serve: an API route that answers
|
||||
* with a redirect (an OAuth connect, a sign-in hand-off), or a page that has
|
||||
* to start from a fresh document because the client state of the old one no
|
||||
* longer belongs to anybody (after the account was deleted).
|
||||
*
|
||||
* In-app page changes use `useRouter().push()` instead.
|
||||
*/
|
||||
export function loadDocument(path: string): void {
|
||||
window.location.assign(path);
|
||||
}
|
||||
Reference in new issue
Block a user