1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-11-23 11:02:35 +03:00

Make the layout wider on "account" pages

This also fixes a bug where a double "layout" was applied to the not
found pages.

It also sets the layout min height to use 100svh instead of 100vh, so
that it doesn't unecessarily scroll on iOS.
This commit is contained in:
Quentin Gliech
2024-02-19 17:40:28 +01:00
parent 90cebeeefc
commit edfcea0419
10 changed files with 95 additions and 67 deletions

View File

@@ -19,11 +19,19 @@
flex-direction: column;
max-width: calc(420px + var(--cpd-space-5x) * 2);
/* Fallback for browsers that do not support 100svh */
min-height: 100vh;
min-height: 100svh;
margin: 0 auto;
padding-inline: var(--cpd-space-5x);
padding-block: var(--cpd-space-12x);
gap: var(--cpd-space-8x);
&.wide {
max-width: calc(520px + var(--cpd-space-5x) * 2);
}
}
@media screen and (min-width: 768px) {

View File

@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import cx from "classnames";
import appConfig from "../../config";
import Footer from "../Footer";
@@ -20,8 +22,9 @@ import styles from "./Layout.module.css";
const Layout: React.FC<{
children?: React.ReactNode;
dontSuspend?: boolean;
}> = ({ children, dontSuspend }) => (
<div className={styles.layoutContainer}>
wide?: boolean;
}> = ({ children, dontSuspend, wide }) => (
<div className={cx(styles.layoutContainer, wide && styles.wide)}>
{children}
<Footer

View File

@@ -15,7 +15,11 @@
.loading-screen {
display: flex;
/* Fallback for browsers that do not support 100svh */
min-height: 100vh;
min-height: 100svh;
justify-content: center;
align-items: center;
}
}

View File

@@ -15,7 +15,6 @@
.nav-bar {
border-bottom: var(--cpd-border-width-1) solid var(--cpd-color-gray-400);
padding: 0 var(--cpd-space-10x);
}
.nav-bar-items {

View File

@@ -21,7 +21,6 @@ import { Provider as UrqlProvider } from "urql";
import ErrorBoundary from "./components/ErrorBoundary";
import GenericError from "./components/GenericError";
import Layout from "./components/Layout";
import LoadingScreen from "./components/LoadingScreen";
import config from "./config";
import { client } from "./graphql";
@@ -51,9 +50,7 @@ createRoot(document.getElementById("root") as HTMLElement).render(
<UrqlProvider value={client}>
<I18nextProvider i18n={i18n}>
<TooltipProvider>
<Layout>
<RouterProvider router={router} context={{ client }} />
</Layout>
<RouterProvider router={router} context={{ client }} />
</TooltipProvider>
</I18nextProvider>
</UrqlProvider>

View File

@@ -16,6 +16,7 @@ import { Outlet, createFileRoute, notFound } from "@tanstack/react-router";
import { useTranslation } from "react-i18next";
import { useQuery } from "urql";
import Layout from "../components/Layout";
import NavBar from "../components/NavBar";
import NavItem from "../components/NavItem";
import UserGreeting from "../components/UserGreeting";
@@ -53,7 +54,7 @@ function Account(): React.ReactElement {
if (user?.__typename !== "User") throw notFound();
return (
<>
<Layout wide>
<UserGreeting user={user} />
<NavBar>
@@ -66,6 +67,6 @@ function Account(): React.ReactElement {
</NavBar>
<Outlet />
</>
</Layout>
);
}

View File

@@ -16,6 +16,7 @@ import { createFileRoute, notFound } from "@tanstack/react-router";
import { useQuery } from "urql";
import OAuth2ClientDetail from "../components/Client/OAuth2ClientDetail";
import Layout from "../components/Layout";
import { graphql } from "../gql";
const QUERY = graphql(/* GraphQL */ `
@@ -49,5 +50,9 @@ function ClientDetail(): React.ReactElement {
const client = result.data?.oauth2Client;
if (!client) throw new Error(); // Should have been caught by the loader
return <OAuth2ClientDetail client={client} />;
return (
<Layout>
<OAuth2ClientDetail client={client} />
</Layout>
);
}

View File

@@ -16,6 +16,7 @@ import { createFileRoute, notFound, redirect } from "@tanstack/react-router";
import { Alert } from "@vector-im/compound-web";
import { useTranslation } from "react-i18next";
import Layout from "../components/Layout";
import { Link } from "../components/Link";
import { graphql } from "../gql";
@@ -79,12 +80,14 @@ function NotFound(): React.ReactElement {
const { t } = useTranslation();
const { id: deviceId } = Route.useParams();
return (
<Alert
type="critical"
title={t("frontend.session_detail.alert.title", { deviceId })}
>
{t("frontend.session_detail.alert.text")}
<Link to="/sessions">{t("frontend.session_detail.alert.button")}</Link>
</Alert>
<Layout>
<Alert
type="critical"
title={t("frontend.session_detail.alert.title", { deviceId })}
>
{t("frontend.session_detail.alert.text")}
<Link to="/sessions">{t("frontend.session_detail.alert.button")}</Link>
</Alert>
</Layout>
);
}

View File

@@ -15,6 +15,7 @@
import { createFileRoute, notFound } from "@tanstack/react-router";
import { useQuery } from "urql";
import Layout from "../components/Layout";
import VerifyEmailComponent from "../components/VerifyEmail";
import { graphql } from "../gql";
@@ -50,5 +51,9 @@ function EmailVerify(): React.ReactElement {
const email = result.data?.userEmail;
if (email == null) throw notFound();
return <VerifyEmailComponent email={email} />;
return (
<Layout>
<VerifyEmailComponent email={email} />
</Layout>
);
}

View File

@@ -22,6 +22,7 @@ import { z } from "zod";
import BlockList from "../components/BlockList";
import { ButtonLink } from "../components/ButtonLink";
import Layout from "../components/Layout";
import LoadingSpinner from "../components/LoadingSpinner";
import PageHeading from "../components/PageHeading";
import { graphql } from "../gql";
@@ -84,56 +85,58 @@ function ResetCrossSigning(): React.ReactNode {
};
return (
<BlockList>
<PageHeading
Icon={IconKey}
title={t("frontend.reset_cross_signing.heading")}
invalid
/>
<Layout>
<BlockList>
<PageHeading
Icon={IconKey}
title={t("frontend.reset_cross_signing.heading")}
invalid
/>
{!result.data && !result.error && (
<>
<Text className="text-justify">
{t("frontend.reset_cross_signing.description")}
</Text>
<Button
kind="primary"
destructive
disabled={result.fetching}
onClick={onClick}
{!result.data && !result.error && (
<>
<Text className="text-justify">
{t("frontend.reset_cross_signing.description")}
</Text>
<Button
kind="primary"
destructive
disabled={result.fetching}
onClick={onClick}
>
{!!result.fetching && <LoadingSpinner inline />}
{t("frontend.reset_cross_signing.button")}
</Button>
</>
)}
{result.data && (
<Alert
type="info"
title={t("frontend.reset_cross_signing.success.title")}
>
{!!result.fetching && <LoadingSpinner inline />}
{t("frontend.reset_cross_signing.button")}
</Button>
</>
)}
{result.data && (
<Alert
type="info"
title={t("frontend.reset_cross_signing.success.title")}
>
{t("frontend.reset_cross_signing.success.description")}
</Alert>
)}
{result.error && (
<Alert
type="critical"
title={t("frontend.reset_cross_signing.failure.title")}
>
{t("frontend.reset_cross_signing.failure.description")}
</Alert>
)}
{t("frontend.reset_cross_signing.success.description")}
</Alert>
)}
{result.error && (
<Alert
type="critical"
title={t("frontend.reset_cross_signing.failure.title")}
>
{t("frontend.reset_cross_signing.failure.description")}
</Alert>
)}
{!deepLink && (
<ButtonLink
to=".."
from={Route.fullPath}
kind="tertiary"
Icon={IconArrowLeft}
>
{t("action.back")}
</ButtonLink>
)}
</BlockList>
{!deepLink && (
<ButtonLink
to=".."
from={Route.fullPath}
kind="tertiary"
Icon={IconArrowLeft}
>
{t("action.back")}
</ButtonLink>
)}
</BlockList>
</Layout>
);
}