fix(confidence-engine): correct legal footer layout
This commit is contained in:
+3
-2
@@ -1,3 +1,4 @@
|
|||||||
|
import React from "react";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import ThemeToggle from "@/components/theme-toggle";
|
import ThemeToggle from "@/components/theme-toggle";
|
||||||
import LogoutButton from "@/components/logout-button";
|
import LogoutButton from "@/components/logout-button";
|
||||||
@@ -11,7 +12,7 @@ export const metadata = {
|
|||||||
export default function RootLayout({ children }) {
|
export default function RootLayout({ children }) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body className="min-h-screen bg-gray-50 text-gray-900">
|
<body className="flex min-h-screen flex-col bg-gray-50 text-gray-900">
|
||||||
<script
|
<script
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: `try { const saved = localStorage.getItem('confidence-engine-theme'); const theme = saved === 'dark' || saved === 'light' ? saved : (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); document.documentElement.dataset.theme = theme; document.documentElement.style.colorScheme = theme; } catch (_) {}`,
|
__html: `try { const saved = localStorage.getItem('confidence-engine-theme'); const theme = saved === 'dark' || saved === 'light' ? saved : (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); document.documentElement.dataset.theme = theme; document.documentElement.style.colorScheme = theme; } catch (_) {}`,
|
||||||
@@ -26,7 +27,7 @@ export default function RootLayout({ children }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
{children}
|
<div className="flex-1">{children}</div>
|
||||||
<footer className="app-chrome border-t border-gray-200/80 px-6 py-5">
|
<footer className="app-chrome border-t border-gray-200/80 px-6 py-5">
|
||||||
<LegalNavigation />
|
<LegalNavigation />
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import LoginForm from "@/components/login-form";
|
|||||||
|
|
||||||
export default function LoginPage() {
|
export default function LoginPage() {
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto min-h-[calc(100vh-57px)] max-w-[1200px] px-6 py-16">
|
<main className="mx-auto max-w-[1200px] px-6 py-16">
|
||||||
<div className="mx-auto flex flex-col gap-y-8 md:grid md:grid-cols-[minmax(0,1fr)_420px] md:gap-x-8 md:items-start">
|
<div className="mx-auto flex flex-col gap-y-8 md:grid md:grid-cols-[minmax(0,1fr)_420px] md:gap-x-8 md:items-start">
|
||||||
{/* Left column wrapper — contents on mobile for flex ordering, block on desktop as one grid cell */}
|
{/* Left column wrapper — contents on mobile for flex ordering, block on desktop as one grid cell */}
|
||||||
<div className="contents md:block">
|
<div className="contents md:block">
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import LegalNavigation from "@/components/legal-navigation";
|
|
||||||
|
|
||||||
export default function LegalPageLayout({ title, children }) {
|
export default function LegalPageLayout({ title, children }) {
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto min-h-[calc(100vh-57px)] max-w-3xl px-6 py-12 sm:py-16">
|
<main className="mx-auto max-w-3xl px-6 py-12 sm:py-16">
|
||||||
<Link href="/login" className="text-sm font-medium text-teal-700 hover:underline">
|
<Link href="/login" className="text-sm font-medium text-teal-700 hover:underline">
|
||||||
Back to sign in
|
Back to sign in
|
||||||
</Link>
|
</Link>
|
||||||
@@ -14,9 +13,6 @@ export default function LegalPageLayout({ title, children }) {
|
|||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
<footer className="mt-8 border-t border-gray-200 pt-5">
|
|
||||||
<LegalNavigation />
|
|
||||||
</footer>
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
readThemePreference,
|
readThemePreference,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
- Public Privacy, Terms, and Cookie pages and shared legal navigation are available at `/privacy`, `/terms`, and `/cookies`.
|
- Public Privacy, Terms, and Cookie pages and shared legal navigation are available at `/privacy`, `/terms`, and `/cookies`.
|
||||||
- The service is positioned as 18+. No cookie-consent banner is used because current browser storage is limited to essential authentication/session storage and functional UI preferences.
|
- The service is positioned as 18+. No cookie-consent banner is used because current browser storage is limited to essential authentication/session storage and functional UI preferences.
|
||||||
- Legal wording remains subject to appropriate professional review.
|
- Legal wording remains subject to appropriate professional review.
|
||||||
|
- Legal navigation is a single global normal-flow footer: it rests at the viewport bottom on short pages, long legal pages push it naturally below their content, and duplicate legal navigation was removed.
|
||||||
|
|
||||||
## Focused-investigation provider outage boundary
|
## Focused-investigation provider outage boundary
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import PrivacyPage from "@/app/privacy/page.jsx";
|
|||||||
import TermsPage from "@/app/terms/page.jsx";
|
import TermsPage from "@/app/terms/page.jsx";
|
||||||
import CookiesPage from "@/app/cookies/page.jsx";
|
import CookiesPage from "@/app/cookies/page.jsx";
|
||||||
import LegalNavigation from "@/components/legal-navigation.jsx";
|
import LegalNavigation from "@/components/legal-navigation.jsx";
|
||||||
|
import RootLayout from "@/app/layout.jsx";
|
||||||
import { middleware } from "@/middleware.js";
|
import { middleware } from "@/middleware.js";
|
||||||
|
|
||||||
describe("public legal pages", () => {
|
describe("public legal pages", () => {
|
||||||
@@ -16,6 +17,16 @@ describe("public legal pages", () => {
|
|||||||
])("renders the %s heading", (heading, Page) => {
|
])("renders the %s heading", (heading, Page) => {
|
||||||
const html = renderToStaticMarkup(<Page />);
|
const html = renderToStaticMarkup(<Page />);
|
||||||
expect(html).toContain(`<h1 class="text-3xl font-bold tracking-tight text-teal-700">${heading}</h1>`);
|
expect(html).toContain(`<h1 class="text-3xl font-bold tracking-tight text-teal-700">${heading}</h1>`);
|
||||||
|
expect(html).not.toContain('aria-label="Legal information"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps the root layout as the single legal navigation owner", () => {
|
||||||
|
const html = renderToStaticMarkup(
|
||||||
|
<RootLayout>
|
||||||
|
<PrivacyPage />
|
||||||
|
</RootLayout>,
|
||||||
|
);
|
||||||
|
expect(html.match(/aria-label="Legal information"/g)).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("exposes all public legal links without cookie consent controls", () => {
|
it("exposes all public legal links without cookie consent controls", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user