Use compliance page logos for auth layout

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-01-30 11:46:46 +04:00
parent aa8bc15233
commit d76ac5b5fa
6 changed files with 255 additions and 87 deletions

View File

@@ -1,17 +1,48 @@
import { useSystemTheme } from "@probo/hooks";
import { Logo } from "@probo/ui";
import type { PropsWithChildren } from "react";
import { type PreloadedQuery, usePreloadedQuery } from "react-relay";
import { Outlet } from "react-router";
import { graphql } from "relay-runtime";
export function AuthLayout(props: PropsWithChildren) {
const { children } = props;
import type { AuthLayoutQuery } from "./__generated__/AuthLayoutQuery.graphql";
export const authLayoutQuery = graphql`
query AuthLayoutQuery {
currentTrustCenter @required(action: THROW) {
logoFileUrl
darkLogoFileUrl
}
}
`;
export function AuthLayout(props: { queryRef: PreloadedQuery<AuthLayoutQuery> }) {
const { queryRef } = props;
const { currentTrustCenter: compliancePage } = usePreloadedQuery<AuthLayoutQuery>(authLayoutQuery, queryRef);
const theme = useSystemTheme();
const logoFileUrl = theme === "dark"
? compliancePage.darkLogoFileUrl ?? compliancePage.logoFileUrl
: compliancePage.logoFileUrl;
return (
<div className="grid grid-cols-1 lg:grid-cols-2 min-h-screen text-txt-primary">
<div className="bg-level-0 flex flex-col items-center justify-center">
<div className="w-full max-w-md px-6">{children}</div>
<div className="w-full max-w-md px-6">
<Outlet />
</div>
</div>
<div className="hidden lg:flex bg-dialog font-bold flex-col items-center justify-center p-8 text-txt-primary lg:p-10">
<div className="flex flex-col items-center justify-center gap-4">
<Logo withPicto className="w-[440px]" />
{logoFileUrl
? (
<img
alt=""
src={logoFileUrl}
className="size-110 rounded-2xl"
/>
)
: <Logo withPicto className="w-110" />}
</div>
</div>
</div>

View File

@@ -0,0 +1,29 @@
import { useEffect } from "react";
import { useQueryLoader } from "react-relay";
import { RelayProvider } from "#/providers/RelayProviders";
import type { AuthLayoutQuery } from "./__generated__/AuthLayoutQuery.graphql";
import { AuthLayout, authLayoutQuery } from "./AuthLayout";
function AuthLayoutQueryLoader() {
const [queryRef, loadQuery] = useQueryLoader<AuthLayoutQuery>(authLayoutQuery);
useEffect(() => {
if (!queryRef) {
return loadQuery({});
}
});
if (!queryRef) return null;
return <AuthLayout queryRef={queryRef} />;
}
export default function AuthLayoutLoader() {
return (
<RelayProvider>
<AuthLayoutQueryLoader />
</RelayProvider>
);
}

View File

@@ -14,7 +14,6 @@ import { useFormWithSchema } from "#/hooks/useFormWithSchema";
import type { ConnectPageMutation } from "./__generated__/ConnectPageMutation.graphql";
import type { ConnectPageQuery } from "./__generated__/ConnectPageQuery.graphql";
import { AuthLayout } from "./AuthLayout";
export const connectPageQuery = graphql`
query ConnectPageQuery {
@@ -126,7 +125,6 @@ export function ConnectPage(props: {
});
return (
<AuthLayout>
<div className="space-y-6 w-full max-w-md mx-auto">
<div className="space-y-2 text-center">
<h1 className="text-3xl font-bold">
@@ -169,6 +167,5 @@ export function ConnectPage(props: {
</Button>
</form>
</div>
</AuthLayout>
);
}

View File

@@ -12,7 +12,6 @@ import { useFormWithSchema } from "#/hooks/useFormWithSchema";
import { getPathPrefix } from "#/utils/pathPrefix";
import type { VerifyMagicLinkPageMutation } from "./__generated__/VerifyMagicLinkPageMutation.graphql";
import { AuthLayout } from "./AuthLayout";
const verifyMagicLinkMutation = graphql`
mutation VerifyMagicLinkPageMutation($input: VerifyMagicLinkInput!) {
@@ -87,7 +86,6 @@ export default function VerifyMagicLinkPagePageMutation() {
});
return (
<AuthLayout>
<div className="space-y-6 w-full max-w-md mx-auto">
<div className="space-y-2 text-center">
<h1 className="text-3xl font-bold">{__("Email Confirmation")}</h1>
@@ -120,6 +118,5 @@ export default function VerifyMagicLinkPagePageMutation() {
</Button>
</form>
</div>
</AuthLayout>
);
}

View File

@@ -0,0 +1,108 @@
/**
* @generated SignedSource<<c3e41c1d38cd6923e718ea03bba5bb44>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type AuthLayoutQuery$variables = Record<PropertyKey, never>;
export type AuthLayoutQuery$data = {
readonly currentTrustCenter: {
readonly darkLogoFileUrl: string | null | undefined;
readonly logoFileUrl: string | null | undefined;
};
};
export type AuthLayoutQuery = {
response: AuthLayoutQuery$data;
variables: AuthLayoutQuery$variables;
};
const node: ConcreteRequest = (function(){
var v0 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "logoFileUrl",
"storageKey": null
},
v1 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "darkLogoFileUrl",
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "AuthLayoutQuery",
"selections": [
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": null,
"concreteType": "TrustCenter",
"kind": "LinkedField",
"name": "currentTrustCenter",
"plural": false,
"selections": [
(v0/*: any*/),
(v1/*: any*/)
],
"storageKey": null
},
"action": "THROW"
}
],
"type": "Query",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [],
"kind": "Operation",
"name": "AuthLayoutQuery",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "TrustCenter",
"kind": "LinkedField",
"name": "currentTrustCenter",
"plural": false,
"selections": [
(v0/*: any*/),
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "92bbf193e99aa98673d1926bd1fdc890",
"id": null,
"metadata": {},
"name": "AuthLayoutQuery",
"operationKind": "query",
"text": "query AuthLayoutQuery {\n currentTrustCenter {\n logoFileUrl\n darkLogoFileUrl\n id\n }\n}\n"
}
};
})();
(node as any).hash = "d76b10f9b919f4224c4c8b478e66b4f1";
export default node;

View File

@@ -1,10 +1,11 @@
import { lazy } from "@probo/react-lazy";
import {
type AppRoute,
loaderFromQueryLoader,
routeFromAppRoute,
withQueryRef,
} from "@probo/routes";
import { Fragment, lazy } from "react";
import { Fragment } from "react";
import { loadQuery } from "react-relay";
import { createBrowserRouter, redirect, useRouteError } from "react-router";
@@ -33,13 +34,18 @@ function ErrorBoundary() {
}
const routes = [
{
Component: lazy(() => import("#/pages/auth/AuthLayoutLoader")),
children: [
{
path: "/connect",
Component: lazy(() => import("./pages/auth/ConnectPageLoader")),
Component: lazy(() => import("#/pages/auth/ConnectPageLoader")),
},
{
path: "/verify-magic-link",
Component: lazy(() => import("./pages/auth/VerifyMagicLinkPage")),
Component: lazy(() => import("#/pages/auth/VerifyMagicLinkPage")),
},
],
},
{
path: "/",