Dashboard v2 lighthouse scores improvements (#1972)

* Metadata improvements

* Accessibility improvements

* Improve performance on mobile
This commit is contained in:
Michał Leszczyk 2022-04-06 11:10:28 +02:00 committed by GitHub
parent d077a27fa9
commit 7bd54359e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 258 additions and 150 deletions

View File

@ -2,8 +2,8 @@ const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = { module.exports = {
siteMetadata: { siteMetadata: {
title: `Accounts Dashboard`, title: "Skynet Account",
siteUrl: `https://www.yourdomain.tld`, siteUrl: `https://account.${process.env.GATSBY_PORTAL_DOMAIN}/`,
}, },
trailingSlash: "never", trailingSlash: "never",
plugins: [ plugins: [

View File

@ -83,13 +83,19 @@ export const APIKey = ({ apiKey, onRemoved, onEdited, onRemovalError }) => {
{isPublic && ( {isPublic && (
<button <button
title="Add or remove skylinks" title="Add or remove skylinks"
aria-label="Add or remove skylinks"
className="p-1 transition-colors hover:text-primary" className="p-1 transition-colors hover:text-primary"
onClick={promptEdit} onClick={promptEdit}
> >
<CogIcon size={22} /> <CogIcon size={22} />
</button> </button>
)} )}
<button title="Delete this API key" className="p-1 transition-colors hover:text-error" onClick={promptRemoval}> <button
title="Delete this API key"
aria-label="Delete this API key"
className="p-1 transition-colors hover:text-error"
onClick={promptRemoval}
>
<TrashIcon size={16} /> <TrashIcon size={16} />
</button> </button>
</span> </span>
@ -121,7 +127,11 @@ export const APIKey = ({ apiKey, onRemoved, onEdited, onRemovalError }) => {
<code className="whitespace-nowrap select-all truncate bg-palette-100 odd:bg-white p-1"> <code className="whitespace-nowrap select-all truncate bg-palette-100 odd:bg-white p-1">
{skylink} {skylink}
</code> </code>
<button className="p-1 transition-colors hover:text-error" onClick={() => removeSkylink(skylink)}> <button
className="p-1 transition-colors hover:text-error"
onClick={() => removeSkylink(skylink)}
aria-label="Remove skylink"
>
<TrashIcon size={16} /> <TrashIcon size={16} />
</button> </button>
</li> </li>

View File

@ -22,7 +22,7 @@ const TooltipContent = styled.div.attrs({
className: "bg-primary-light/10 text-palette-600 py-2 px-4 ", className: "bg-primary-light/10 text-palette-600 py-2 px-4 ",
})``; })``;
export const CopyButton = ({ value, className }) => { export const CopyButton = ({ value, className, ariaLabel = "Copy" }) => {
const containerRef = useRef(); const containerRef = useRef();
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const [timer, setTimer] = useState(null); const [timer, setTimer] = useState(null);
@ -39,7 +39,7 @@ export const CopyButton = ({ value, className }) => {
return ( return (
<div ref={containerRef} className={`inline-flex relative overflow-visible pr-2 ${className ?? ""}`}> <div ref={containerRef} className={`inline-flex relative overflow-visible pr-2 ${className ?? ""}`}>
<Button onClick={handleCopy} className={copied ? "text-primary" : ""}> <Button onClick={handleCopy} className={copied ? "text-primary" : ""} aria-label={ariaLabel}>
<CopyIcon size={16} /> <CopyIcon size={16} />
</Button> </Button>
<TooltipContainer $visible={copied}> <TooltipContainer $visible={copied}>

View File

@ -101,7 +101,6 @@ export default function CurrentUsage() {
> >
UPGRADE UPGRADE
</Link>{" "} </Link>{" "}
{/* TODO: proper URL */}
<span>{usage.filesLimit}</span> <span>{usage.filesLimit}</span>
</span> </span>
</div> </div>

View File

@ -84,19 +84,19 @@ export default function FileTable({ items }) {
<TableCell className="w-[180px]">{date}</TableCell> <TableCell className="w-[180px]">{date}</TableCell>
<TableCell className="hidden lg:table-cell pr-6 !overflow-visible"> <TableCell className="hidden lg:table-cell pr-6 !overflow-visible">
<div className="flex items-center"> <div className="flex items-center">
<CopyButton value={skylink} className="mr-2" /> <CopyButton value={skylink} className="mr-2" aria-label="Copy skylink" />
<span className="w-full inline-block truncate">{skylink}</span> <span className="w-full inline-block truncate">{skylink}</span>
</div> </div>
</TableCell> </TableCell>
<TableCell className="w-[100px] !overflow-visible"> <TableCell className="w-[100px] !overflow-visible">
<div className="flex text-palette-600 gap-4"> <div className="flex text-palette-600 gap-4">
<PopoverMenu options={buildShareMenu(item)} openClassName="text-primary"> <PopoverMenu options={buildShareMenu(item)} openClassName="text-primary">
<button> <button aria-label="Share this skylink">
<ShareIcon size={22} /> <ShareIcon size={22} />
</button> </button>
</PopoverMenu> </PopoverMenu>
<PopoverMenu options={buildOptionsMenu(item)} openClassName="text-primary"> <PopoverMenu options={buildOptionsMenu(item)} openClassName="text-primary">
<button> <button aria-label="Manage this skylink">
<CogIcon /> <CogIcon />
</button> </button>
</PopoverMenu> </PopoverMenu>

View File

@ -0,0 +1,27 @@
import { Helmet } from "react-helmet";
import { graphql, useStaticQuery } from "gatsby";
export const Metadata = ({ children }) => {
const { site } = useStaticQuery(
graphql`
query Q {
site {
siteMetadata {
title
}
}
}
`
);
const { title } = site.siteMetadata;
return (
<Helmet htmlAttributes={{ lang: "en" }} titleTemplate={`%s | ${title}`} defaultTitle={title}>
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<meta name="description" content="Manage your Skynet uploads, account subscription, settings and API keys" />
<link rel="preconnect" href={`https://${process.env.GATSBY_PORTAL_DOMAIN}/`} />
{children}
</Helmet>
);
};

View File

@ -0,0 +1 @@
export * from "./Metadata";

View File

@ -11,7 +11,7 @@ export const Modal = ({ children, className, onClose }) => (
<ModalPortal> <ModalPortal>
<Overlay onClick={onClose}> <Overlay onClick={onClose}>
<div className={cn("relative w-modal max-w-modal shadow-sm rounded")}> <div className={cn("relative w-modal max-w-modal shadow-sm rounded")}>
<button onClick={onClose} className="absolute top-[20px] right-[20px]"> <button onClick={onClose} className="absolute top-[20px] right-[20px]" aria-label="Close">
<PlusIcon size={14} className="rotate-45" /> <PlusIcon size={14} className="rotate-45" />
</button> </button>
<Panel className={cn("px-8 py-6 sm:px-12 sm:py-10", className)}>{children}</Panel> <Panel className={cn("px-8 py-6 sm:px-12 sm:py-10", className)}>{children}</Panel>

View File

@ -94,6 +94,7 @@ export const NavBar = () => {
partiallyActive partiallyActive
/> />
<DropdownMenuLink <DropdownMenuLink
as="button"
onClick={onLogout} onClick={onLogout}
activeClassName="text-primary" activeClassName="text-primary"
className="cursor-pointer" className="cursor-pointer"

View File

@ -12,6 +12,7 @@ export default function Bullets({ visibleSlides, activeIndex, allSlides, changeS
.map((_, index) => ( .map((_, index) => (
<button <button
key={index} key={index}
aria-label={`Slide ${index + 1}`}
type="button" type="button"
className={`rounded-full w-3 h-3 ${activeIndex === index ? "bg-primary" : "border-2 cursor-pointer"}`} className={`rounded-full w-3 h-3 ${activeIndex === index ? "bg-primary" : "border-2 cursor-pointer"}`}
onClick={(event) => changeSlide(event, index)} onClick={(event) => changeSlide(event, index)}

View File

@ -105,7 +105,11 @@ const Uploader = ({ mode }) => {
</div> </div>
) : ( ) : (
<div className="p-5"> <div className="p-5">
<Button $primary className="w-[40px] h-[40px] !p-0 inline-flex justify-center items-center"> <Button
$primary
className="w-[40px] h-[40px] !p-0 inline-flex justify-center items-center"
aria-label="Upload new file"
>
<PlusIcon size={12} /> <PlusIcon size={12} />
</Button> </Button>
<span className="ml-4">Add, or drop your files here</span> <span className="ml-4">Add, or drop your files here</span>

View File

@ -44,7 +44,7 @@ export const AddAPIKeyForm = forwardRef(({ onSuccess, type }, ref) => {
<code className="p-2 rounded border border-palette-200 text-xs selection:bg-primary/30 truncate"> <code className="p-2 rounded border border-palette-200 text-xs selection:bg-primary/30 truncate">
{generatedKey} {generatedKey}
</code> </code>
<CopyButton value={generatedKey} className="whitespace-nowrap" /> <CopyButton value={generatedKey} className="whitespace-nowrap" aria-label="Copy the new API key" />
</div> </div>
</Alert> </Alert>
)} )}
@ -94,7 +94,7 @@ export const AddAPIKeyForm = forwardRef(({ onSuccess, type }, ref) => {
{isSubmitting ? ( {isSubmitting ? (
<CircledProgressIcon size={38} className="text-palette-300 animate-[spin_3s_linear_infinite]" /> <CircledProgressIcon size={38} className="text-palette-300 animate-[spin_3s_linear_infinite]" />
) : ( ) : (
<Button type="submit" className="px-2.5"> <Button type="submit" className="px-2.5" aria-label="Create general API key">
<PlusIcon size={14} /> <PlusIcon size={14} />
</Button> </Button>
)} )}

View File

@ -59,7 +59,7 @@ export const AddPublicAPIKeyForm = forwardRef(({ onSuccess }, ref) => {
<code className="p-2 rounded border border-palette-200 text-xs selection:bg-primary/30 truncate"> <code className="p-2 rounded border border-palette-200 text-xs selection:bg-primary/30 truncate">
{generatedKey} {generatedKey}
</code> </code>
<CopyButton value={generatedKey} className="whitespace-nowrap" /> <CopyButton value={generatedKey} className="whitespace-nowrap" aria-label="Copy the new public API key" />
</div> </div>
</Alert> </Alert>
)} )}
@ -137,7 +137,7 @@ export const AddPublicAPIKeyForm = forwardRef(({ onSuccess }, ref) => {
touched={skylinksTouched[index]} touched={skylinksTouched[index]}
/> />
<span className="w-[24px] shrink-0 mt-3"> <span className="w-[24px] shrink-0 mt-3">
<button type="button" onClick={() => remove(index)}> <button type="button" onClick={() => remove(index)} aria-label="Remove this skylink">
<TrashIcon size={16} /> <TrashIcon size={16} />
</button> </button>
</span> </span>
@ -160,6 +160,7 @@ export const AddPublicAPIKeyForm = forwardRef(({ onSuccess }, ref) => {
/> />
<button <button
type="button" type="button"
aria-label="Add this skylink"
onClick={() => appendSkylink(values.nextSkylink)} onClick={() => appendSkylink(values.nextSkylink)}
className={cn("shrink-0 mt-1.5 w-[24px] h-[24px]", { className={cn("shrink-0 mt-1.5 w-[24px] h-[24px]", {
"text-palette-300 cursor-not-allowed": isNextSkylinkInvalid, "text-palette-300 cursor-not-allowed": isNextSkylinkInvalid,

View File

@ -48,7 +48,7 @@ export const AddSkylinkToAPIKeyForm = ({ addSkylink }) => (
{isSubmitting ? ( {isSubmitting ? (
<CircledProgressIcon size={38} className="text-palette-300 animate-[spin_3s_linear_infinite]" /> <CircledProgressIcon size={38} className="text-palette-300 animate-[spin_3s_linear_infinite]" />
) : ( ) : (
<Button type="submit" className="px-2.5"> <Button type="submit" className="px-2.5" aria-label="Add this skylink">
<PlusIcon size={14} /> <PlusIcon size={14} />
</Button> </Button>
)} )}

View File

@ -4,6 +4,7 @@ import { navigate } from "gatsby";
import AuthLayout from "../../layouts/AuthLayout"; import AuthLayout from "../../layouts/AuthLayout";
import { LoginForm } from "../../components/forms"; import { LoginForm } from "../../components/forms";
import { useUser } from "../../contexts/user"; import { useUser } from "../../contexts/user";
import { Metadata } from "../../components/Metadata";
const LoginPage = ({ location }) => { const LoginPage = ({ location }) => {
const { user, mutate: refreshUserState } = useUser(); const { user, mutate: refreshUserState } = useUser();
@ -17,6 +18,10 @@ const LoginPage = ({ location }) => {
}, [user, redirectTo]); }, [user, redirectTo]);
return ( return (
<>
<Metadata>
<title>Sign In</title>
</Metadata>
<div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen"> <div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen">
<div className="mb-4 md:mb-16"> <div className="mb-4 md:mb-16">
<img src="/images/logo-black-text.svg" alt="Skynet" /> <img src="/images/logo-black-text.svg" alt="Skynet" />
@ -27,6 +32,7 @@ const LoginPage = ({ location }) => {
}} }}
/> />
</div> </div>
</>
); );
}; };

View File

@ -4,6 +4,7 @@ import AuthLayout from "../../layouts/AuthLayout";
import { RecoveryForm } from "../../components/forms/RecoveryForm"; import { RecoveryForm } from "../../components/forms/RecoveryForm";
import HighlightedLink from "../../components/HighlightedLink"; import HighlightedLink from "../../components/HighlightedLink";
import { Metadata } from "../../components/Metadata";
const State = { const State = {
Pure: "PURE", Pure: "PURE",
@ -15,6 +16,10 @@ const ResetPasswordPage = () => {
const [state, setState] = useState(State.Pure); const [state, setState] = useState(State.Pure);
return ( return (
<>
<Metadata>
<title>Reset Password</title>
</Metadata>
<div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen"> <div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen">
<div className="mb-4 md:mb-16"> <div className="mb-4 md:mb-16">
<img src="/images/logo-black-text.svg" alt="Skynet" /> <img src="/images/logo-black-text.svg" alt="Skynet" />
@ -40,6 +45,7 @@ const ResetPasswordPage = () => {
</p> </p>
</div> </div>
</div> </div>
</>
); );
}; };

View File

@ -9,6 +9,7 @@ import HighlightedLink from "../../components/HighlightedLink";
import { SignUpForm } from "../../components/forms/SignUpForm"; import { SignUpForm } from "../../components/forms/SignUpForm";
import { usePortalSettings } from "../../contexts/portal-settings"; import { usePortalSettings } from "../../contexts/portal-settings";
import { PlansProvider, usePlans } from "../../contexts/plans"; import { PlansProvider, usePlans } from "../../contexts/plans";
import { Metadata } from "../../components/Metadata";
const FreePortalHeader = () => { const FreePortalHeader = () => {
const { plans } = usePlans(); const { plans } = usePlans();
@ -57,6 +58,9 @@ const SignUpPage = () => {
return ( return (
<PlansProvider> <PlansProvider>
<Metadata>
<title>Sign Up</title>
</Metadata>
<div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen"> <div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen">
<div className="mb-4 md:mb-16"> <div className="mb-4 md:mb-16">
<img src="/images/logo-black-text.svg" alt="Skynet" /> <img src="/images/logo-black-text.svg" alt="Skynet" />

View File

@ -1,16 +1,21 @@
import * as React from "react"; import * as React from "react";
import { useSearchParam } from "react-use";
import DashboardLayout from "../layouts/DashboardLayout"; import DashboardLayout from "../layouts/DashboardLayout";
import { Panel } from "../components/Panel"; import { Panel } from "../components/Panel";
import { Tab, TabPanel, Tabs } from "../components/Tabs"; import { Tab, TabPanel, Tabs } from "../components/Tabs";
import { Metadata } from "../components/Metadata";
import FileList from "../components/FileList/FileList"; import FileList from "../components/FileList/FileList";
import { useSearchParam } from "react-use";
const FilesPage = () => { const FilesPage = () => {
const defaultTab = useSearchParam("tab"); const defaultTab = useSearchParam("tab");
return ( return (
<>
<Metadata>
<title>My Files</title>
</Metadata>
<Panel title="Files"> <Panel title="Files">
<Tabs defaultTab={defaultTab || "uploads"}> <Tabs defaultTab={defaultTab || "uploads"}>
<Tab id="uploads" title="Uploads" /> <Tab id="uploads" title="Uploads" />
@ -23,6 +28,7 @@ const FilesPage = () => {
</TabPanel> </TabPanel>
</Tabs> </Tabs>
</Panel> </Panel>
</>
); );
}; };

View File

@ -13,6 +13,7 @@ import CurrentUsage from "../components/CurrentUsage";
import Uploader from "../components/Uploader/Uploader"; import Uploader from "../components/Uploader/Uploader";
import CurrentPlan from "../components/CurrentPlan"; import CurrentPlan from "../components/CurrentPlan";
import { FullScreenLoadingIndicator } from "../components/LoadingIndicator"; import { FullScreenLoadingIndicator } from "../components/LoadingIndicator";
import { Metadata } from "../components/Metadata";
import useUpgradeRedirect from "../hooks/useUpgradeRedirect"; import useUpgradeRedirect from "../hooks/useUpgradeRedirect";
const IndexPage = () => { const IndexPage = () => {
@ -24,6 +25,13 @@ const IndexPage = () => {
} }
return ( return (
<>
<Metadata>
<title>Dashboard</title>
</Metadata>
{verifyingSubscription ? (
<FullScreenLoadingIndicator />
) : (
<PlansProvider> <PlansProvider>
<div className="w-full"> <div className="w-full">
<Slider <Slider
@ -69,6 +77,8 @@ const IndexPage = () => {
</div> </div>
)} )}
</PlansProvider> </PlansProvider>
)}
</>
); );
}; };

View File

@ -7,6 +7,7 @@ import { AddAPIKeyForm, APIKeyType } from "../../components/forms/AddAPIKeyForm"
import { APIKeyList } from "../../components/APIKeyList/APIKeyList"; import { APIKeyList } from "../../components/APIKeyList/APIKeyList";
import { Alert } from "../../components/Alert"; import { Alert } from "../../components/Alert";
import { AddPublicAPIKeyForm } from "../../components/forms/AddPublicAPIKeyForm"; import { AddPublicAPIKeyForm } from "../../components/forms/AddPublicAPIKeyForm";
import { Metadata } from "../../components/Metadata";
const APIKeysPage = () => { const APIKeysPage = () => {
const { data: apiKeys = [], mutate: reloadKeys, error } = useSWR("user/apikeys"); const { data: apiKeys = [], mutate: reloadKeys, error } = useSWR("user/apikeys");
@ -29,6 +30,9 @@ const APIKeysPage = () => {
return ( return (
<> <>
<Metadata>
<title>API Keys</title>
</Metadata>
<div className="flex flex-col xl:flex-row"> <div className="flex flex-col xl:flex-row">
<div className="flex flex-col gap-10 lg:shrink-0 lg:max-w-[576px] xl:max-w-[524px]"> <div className="flex flex-col gap-10 lg:shrink-0 lg:max-w-[576px] xl:max-w-[524px]">
<div> <div>

View File

@ -4,6 +4,7 @@ import UserSettingsLayout from "../../layouts/UserSettingsLayout";
import { Switch } from "../../components/Switch"; import { Switch } from "../../components/Switch";
import { Button } from "../../components/Button"; import { Button } from "../../components/Button";
import { Metadata } from "../../components/Metadata";
const useExportOptions = () => { const useExportOptions = () => {
const [pinnedFiles, setPinnedFiles] = useState(false); const [pinnedFiles, setPinnedFiles] = useState(false);
@ -29,6 +30,9 @@ const ExportPage = () => {
return ( return (
<> <>
<Metadata>
<title>Export</title>
</Metadata>
<div className="flex flex-col xl:flex-row"> <div className="flex flex-col xl:flex-row">
<div className="flex flex-col gap-10 lg:shrink-0 lg:max-w-[576px] xl:max-w-[524px]"> <div className="flex flex-col gap-10 lg:shrink-0 lg:max-w-[576px] xl:max-w-[524px]">
<section> <section>

View File

@ -7,6 +7,7 @@ import { AccountSettingsForm } from "../../components/forms/AccountSettingsForm"
import { Modal } from "../../components/Modal/Modal"; import { Modal } from "../../components/Modal/Modal";
import { AccountRemovalForm } from "../../components/forms/AccountRemovalForm"; import { AccountRemovalForm } from "../../components/forms/AccountRemovalForm";
import { Alert } from "../../components/Alert"; import { Alert } from "../../components/Alert";
import { Metadata } from "../../components/Metadata";
const State = { const State = {
Pure: "PURE", Pure: "PURE",
@ -39,6 +40,9 @@ const AccountPage = () => {
return ( return (
<> <>
<Metadata>
<title>Settings</title>
</Metadata>
<div className="flex flex-col xl:flex-row"> <div className="flex flex-col xl:flex-row">
<div className="flex flex-col gap-10 lg:shrink-0 lg:max-w-[576px] xl:max-w-[524px]"> <div className="flex flex-col gap-10 lg:shrink-0 lg:max-w-[576px] xl:max-w-[524px]">
<section> <section>

View File

@ -1,13 +1,17 @@
import * as React from "react"; import * as React from "react";
import { StaticImage } from "gatsby-plugin-image";
import UserSettingsLayout from "../../layouts/UserSettingsLayout"; import UserSettingsLayout from "../../layouts/UserSettingsLayout";
import { Switch } from "../../components/Switch"; import { Switch } from "../../components/Switch";
import { StaticImage } from "gatsby-plugin-image"; import { Metadata } from "../../components/Metadata";
const NotificationsPage = () => { const NotificationsPage = () => {
return ( return (
<> <>
<Metadata>
<title>Notifications</title>
</Metadata>
<div className="flex"> <div className="flex">
<div className="flex flex-col gap-10 lg:shrink-0 lg:max-w-[576px] xl:max-w-[524px]"> <div className="flex flex-col gap-10 lg:shrink-0 lg:max-w-[576px] xl:max-w-[524px]">
<h4>Notifications</h4> <h4>Notifications</h4>

View File

@ -13,6 +13,7 @@ import { Button } from "../components/Button";
import { usePortalSettings } from "../contexts/portal-settings"; import { usePortalSettings } from "../contexts/portal-settings";
import { Alert } from "../components/Alert"; import { Alert } from "../components/Alert";
import HighlightedLink from "../components/HighlightedLink"; import HighlightedLink from "../components/HighlightedLink";
import { Metadata } from "../components/Metadata";
const PAID_PORTAL_BREAKPOINTS = [ const PAID_PORTAL_BREAKPOINTS = [
{ {
@ -88,6 +89,9 @@ const PlansSlider = () => {
return ( return (
<div className="w-full mb-24"> <div className="w-full mb-24">
<Metadata>
<title>Upgrade</title>
</Metadata>
{settings.isSubscriptionRequired && !activePlan && ( {settings.isSubscriptionRequired && !activePlan && (
<Alert $variant="info" className="mb-6"> <Alert $variant="info" className="mb-6">
<p className="font-semibold mt-0">This Skynet portal requires a paid subscription.</p> <p className="font-semibold mt-0">This Skynet portal requires a paid subscription.</p>

View File

@ -5,6 +5,7 @@ import { AllUsersAuthLayout } from "../../layouts/AuthLayout";
import HighlightedLink from "../../components/HighlightedLink"; import HighlightedLink from "../../components/HighlightedLink";
import accountsService from "../../services/accountsService"; import accountsService from "../../services/accountsService";
import { Metadata } from "../../components/Metadata";
const State = { const State = {
Pure: "PURE", Pure: "PURE",
@ -52,6 +53,10 @@ const EmailConfirmationPage = ({ location }) => {
}, [token]); }, [token]);
return ( return (
<>
<Metadata>
<title>Confirm E-mail Address</title>
</Metadata>
<div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen"> <div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen">
<div className="mb-4 md:mb-16"> <div className="mb-4 md:mb-16">
<img src="/images/logo-black-text.svg" alt="Skynet" /> <img src="/images/logo-black-text.svg" alt="Skynet" />
@ -70,6 +75,7 @@ const EmailConfirmationPage = ({ location }) => {
{state === State.Failure && <p className="text-error">Something went wrong, please try again later.</p>} {state === State.Failure && <p className="text-error">Something went wrong, please try again later.</p>}
</div> </div>
</div> </div>
</>
); );
}; };

View File

@ -5,6 +5,7 @@ import AuthLayout from "../../layouts/AuthLayout";
import { ResetPasswordForm } from "../../components/forms/ResetPasswordForm"; import { ResetPasswordForm } from "../../components/forms/ResetPasswordForm";
import HighlightedLink from "../../components/HighlightedLink"; import HighlightedLink from "../../components/HighlightedLink";
import { Metadata } from "../../components/Metadata";
const State = { const State = {
Pure: "PURE", Pure: "PURE",
@ -19,6 +20,10 @@ const RecoverPage = ({ location }) => {
const [state, setState] = useState(State.Pure); const [state, setState] = useState(State.Pure);
return ( return (
<>
<Metadata>
<title>Recover Your Account</title>
</Metadata>
<div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen"> <div className="bg-white px-8 py-10 md:py-32 lg:px-16 xl:px-28 min-h-screen">
<div className="mb-4 md:mb-16"> <div className="mb-4 md:mb-16">
<img src="/images/logo-black-text.svg" alt="Skynet" /> <img src="/images/logo-black-text.svg" alt="Skynet" />
@ -48,6 +53,7 @@ const RecoverPage = ({ location }) => {
Suddenly remembered your old password? <HighlightedLink to="/auth/login">Sign in</HighlightedLink> Suddenly remembered your old password? <HighlightedLink to="/auth/login">Sign in</HighlightedLink>
</p> </p>
</div> </div>
</>
); );
}; };

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB