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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -16,6 +16,7 @@ import { createFileRoute, notFound } from "@tanstack/react-router";
import { useQuery } from "urql"; import { useQuery } from "urql";
import OAuth2ClientDetail from "../components/Client/OAuth2ClientDetail"; import OAuth2ClientDetail from "../components/Client/OAuth2ClientDetail";
import Layout from "../components/Layout";
import { graphql } from "../gql"; import { graphql } from "../gql";
const QUERY = graphql(/* GraphQL */ ` const QUERY = graphql(/* GraphQL */ `
@@ -49,5 +50,9 @@ function ClientDetail(): React.ReactElement {
const client = result.data?.oauth2Client; const client = result.data?.oauth2Client;
if (!client) throw new Error(); // Should have been caught by the loader 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 { Alert } from "@vector-im/compound-web";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import Layout from "../components/Layout";
import { Link } from "../components/Link"; import { Link } from "../components/Link";
import { graphql } from "../gql"; import { graphql } from "../gql";
@@ -79,12 +80,14 @@ function NotFound(): React.ReactElement {
const { t } = useTranslation(); const { t } = useTranslation();
const { id: deviceId } = Route.useParams(); const { id: deviceId } = Route.useParams();
return ( return (
<Alert <Layout>
type="critical" <Alert
title={t("frontend.session_detail.alert.title", { deviceId })} 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> {t("frontend.session_detail.alert.text")}
</Alert> <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 { createFileRoute, notFound } from "@tanstack/react-router";
import { useQuery } from "urql"; import { useQuery } from "urql";
import Layout from "../components/Layout";
import VerifyEmailComponent from "../components/VerifyEmail"; import VerifyEmailComponent from "../components/VerifyEmail";
import { graphql } from "../gql"; import { graphql } from "../gql";
@@ -50,5 +51,9 @@ function EmailVerify(): React.ReactElement {
const email = result.data?.userEmail; const email = result.data?.userEmail;
if (email == null) throw notFound(); 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 BlockList from "../components/BlockList";
import { ButtonLink } from "../components/ButtonLink"; import { ButtonLink } from "../components/ButtonLink";
import Layout from "../components/Layout";
import LoadingSpinner from "../components/LoadingSpinner"; import LoadingSpinner from "../components/LoadingSpinner";
import PageHeading from "../components/PageHeading"; import PageHeading from "../components/PageHeading";
import { graphql } from "../gql"; import { graphql } from "../gql";
@@ -84,56 +85,58 @@ function ResetCrossSigning(): React.ReactNode {
}; };
return ( return (
<BlockList> <Layout>
<PageHeading <BlockList>
Icon={IconKey} <PageHeading
title={t("frontend.reset_cross_signing.heading")} Icon={IconKey}
invalid title={t("frontend.reset_cross_signing.heading")}
/> invalid
/>
{!result.data && !result.error && ( {!result.data && !result.error && (
<> <>
<Text className="text-justify"> <Text className="text-justify">
{t("frontend.reset_cross_signing.description")} {t("frontend.reset_cross_signing.description")}
</Text> </Text>
<Button <Button
kind="primary" kind="primary"
destructive destructive
disabled={result.fetching} disabled={result.fetching}
onClick={onClick} 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.success.description")}
{t("frontend.reset_cross_signing.button")} </Alert>
</Button> )}
</> {result.error && (
)} <Alert
{result.data && ( type="critical"
<Alert title={t("frontend.reset_cross_signing.failure.title")}
type="info" >
title={t("frontend.reset_cross_signing.success.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 && ( {!deepLink && (
<ButtonLink <ButtonLink
to=".." to=".."
from={Route.fullPath} from={Route.fullPath}
kind="tertiary" kind="tertiary"
Icon={IconArrowLeft} Icon={IconArrowLeft}
> >
{t("action.back")} {t("action.back")}
</ButtonLink> </ButtonLink>
)} )}
</BlockList> </BlockList>
</Layout>
); );
} }