6 changed files with 201 additions and 1 deletions
@ -0,0 +1,65 @@ |
|||||||
|
import { Trans, useTranslation } from "react-i18next"; |
||||||
|
import { useNavigate } from "react-router-dom"; |
||||||
|
|
||||||
|
import { Icons } from "@/components/Icon"; |
||||||
|
import { Stepper } from "@/components/layout/Stepper"; |
||||||
|
import { CenterContainer } from "@/components/layout/ThinContainer"; |
||||||
|
import { VerticalLine } from "@/components/layout/VerticalLine"; |
||||||
|
import { Heading2, Paragraph } from "@/components/utils/Text"; |
||||||
|
import { MinimalPageLayout } from "@/pages/layouts/MinimalPageLayout"; |
||||||
|
import { Card, CardContent, Link } from "@/pages/migration/utils"; |
||||||
|
import { PageTitle } from "@/pages/parts/util/PageTitle"; |
||||||
|
|
||||||
|
export function MigrationPage() { |
||||||
|
const navigate = useNavigate(); |
||||||
|
const { t } = useTranslation(); |
||||||
|
|
||||||
|
return ( |
||||||
|
<MinimalPageLayout> |
||||||
|
<PageTitle subpage k="global.pages.migration" /> |
||||||
|
<CenterContainer> |
||||||
|
<Stepper steps={2} current={1} className="mb-12" /> |
||||||
|
<Heading2 className="!mt-0 !text-3xl max-w-[435px]"> |
||||||
|
{t("migration.start.title")} |
||||||
|
</Heading2> |
||||||
|
<Paragraph className="max-w-[320px]"> |
||||||
|
{t("migration.start.explainer")} |
||||||
|
</Paragraph> |
||||||
|
|
||||||
|
<div className="w-full flex flex-col md:flex-row gap-3"> |
||||||
|
<Card onClick={() => navigate("/migration/direct")}> |
||||||
|
<CardContent |
||||||
|
colorClass="!text-onboarding-best" |
||||||
|
title={t("migration.start.options.direct.title")} |
||||||
|
subtitle={t("migration.start.options.direct.quality")} |
||||||
|
description={ |
||||||
|
<Trans i18nKey="migration.start.options.direct.description" /> |
||||||
|
} |
||||||
|
icon={Icons.CLOUD_ARROW_UP} |
||||||
|
> |
||||||
|
<Link>{t("migration.start.options.direct.action")}</Link> |
||||||
|
</CardContent> |
||||||
|
</Card> |
||||||
|
<div className="hidden md:grid grid-rows-[1fr,auto,1fr] justify-center gap-4"> |
||||||
|
<VerticalLine className="items-end" /> |
||||||
|
<span className="text-xs uppercase font-bold"> |
||||||
|
{t("migration.start.options.or")} |
||||||
|
</span> |
||||||
|
<VerticalLine /> |
||||||
|
</div> |
||||||
|
<Card onClick={() => navigate("/migration/download")}> |
||||||
|
<CardContent |
||||||
|
colorClass="!text-migration-good" |
||||||
|
title={t("migration.start.options.download.title")} |
||||||
|
subtitle={t("migration.start.options.download.quality")} |
||||||
|
description={t("migration.start.options.download.description")} |
||||||
|
icon={Icons.FILE_ARROW_DOWN} |
||||||
|
> |
||||||
|
<Link>{t("migration.start.options.download.action")}</Link> |
||||||
|
</CardContent> |
||||||
|
</Card> |
||||||
|
</div> |
||||||
|
</CenterContainer> |
||||||
|
</MinimalPageLayout> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
import { CenterContainer } from "@/components/layout/ThinContainer"; |
||||||
|
import { MinimalPageLayout } from "@/pages/layouts/MinimalPageLayout"; |
||||||
|
import { PageTitle } from "@/pages/parts/util/PageTitle"; |
||||||
|
|
||||||
|
export function MigrationDirectPage() { |
||||||
|
return ( |
||||||
|
<MinimalPageLayout> |
||||||
|
<PageTitle subpage k="global.pages.migration" /> |
||||||
|
<CenterContainer>Hi</CenterContainer> |
||||||
|
</MinimalPageLayout> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,92 @@ |
|||||||
|
import classNames from "classnames"; |
||||||
|
import { ReactNode } from "react"; |
||||||
|
import { useNavigate } from "react-router-dom"; |
||||||
|
|
||||||
|
import { Icon, Icons } from "@/components/Icon"; |
||||||
|
import { Heading2, Heading3, Paragraph } from "@/components/utils/Text"; |
||||||
|
|
||||||
|
export function Card(props: { |
||||||
|
children?: React.ReactNode; |
||||||
|
className?: string; |
||||||
|
onClick?: () => void; |
||||||
|
}) { |
||||||
|
return ( |
||||||
|
<div |
||||||
|
className={classNames( |
||||||
|
{ |
||||||
|
"bg-onboarding-card duration-300 border border-onboarding-border rounded-lg p-7": |
||||||
|
true, |
||||||
|
"hover:bg-onboarding-cardHover transition-colors cursor-pointer": |
||||||
|
!!props.onClick, |
||||||
|
}, |
||||||
|
props.className, |
||||||
|
)} |
||||||
|
onClick={props.onClick} |
||||||
|
> |
||||||
|
{props.children} |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export function CardContent(props: { |
||||||
|
title: ReactNode; |
||||||
|
description: ReactNode; |
||||||
|
subtitle: ReactNode; |
||||||
|
colorClass: string; |
||||||
|
children?: React.ReactNode; |
||||||
|
icon: Icons; |
||||||
|
}) { |
||||||
|
return ( |
||||||
|
<div className="grid grid-rows-[1fr,auto] h-full"> |
||||||
|
<div> |
||||||
|
<Icon |
||||||
|
icon={props.icon} |
||||||
|
className={classNames("text-4xl mb-8 block", props.colorClass)} |
||||||
|
/> |
||||||
|
<Heading3 |
||||||
|
className={classNames( |
||||||
|
"!mt-0 !mb-0 !text-xs uppercase", |
||||||
|
props.colorClass, |
||||||
|
)} |
||||||
|
> |
||||||
|
{props.subtitle} |
||||||
|
</Heading3> |
||||||
|
<Heading2 className="!mb-0 !mt-1 !text-base">{props.title}</Heading2> |
||||||
|
<Paragraph className="max-w-[320px] !my-4"> |
||||||
|
{props.description} |
||||||
|
</Paragraph> |
||||||
|
</div> |
||||||
|
<div>{props.children}</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export function Link(props: { |
||||||
|
children?: React.ReactNode; |
||||||
|
to?: string; |
||||||
|
href?: string; |
||||||
|
className?: string; |
||||||
|
target?: "_blank"; |
||||||
|
}) { |
||||||
|
const navigate = useNavigate(); |
||||||
|
return ( |
||||||
|
<a |
||||||
|
onClick={() => { |
||||||
|
if (props.to) navigate(props.to); |
||||||
|
}} |
||||||
|
href={props.href} |
||||||
|
target={props.target} |
||||||
|
className={classNames( |
||||||
|
"text-onboarding-link cursor-pointer inline-flex gap-2 items-center group hover:opacity-75 transition-opacity", |
||||||
|
props.className, |
||||||
|
)} |
||||||
|
rel="noreferrer" |
||||||
|
> |
||||||
|
{props.children} |
||||||
|
<Icon |
||||||
|
icon={Icons.ARROW_RIGHT} |
||||||
|
className="group-hover:translate-x-0.5 transition-transform text-xl group-active:translate-x-0" |
||||||
|
/> |
||||||
|
</a> |
||||||
|
); |
||||||
|
} |
Loading…
Reference in new issue