mirror of
https://github.com/lukevella/rallly.git
synced 2025-08-06 09:59:00 +02:00
✨ Animate in and out of login page (#767)
This commit is contained in:
parent
b8ce7522dc
commit
40af70e08f
6 changed files with 67 additions and 24 deletions
|
@ -7,7 +7,7 @@ export const AuthLayout = (
|
||||||
<>
|
<>
|
||||||
<NextSeo nofollow={true} title={props.title} />
|
<NextSeo nofollow={true} title={props.title} />
|
||||||
<div className="flex h-screen items-center justify-center p-4">
|
<div className="flex h-screen items-center justify-center p-4">
|
||||||
<div className="animate-popIn space-y-2 rounded-md border bg-white p-6 text-center shadow-sm">
|
<div className="space-y-2 rounded-md border bg-white p-6 text-center shadow-sm">
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { ClockIcon, ListIcon, LogInIcon } from "@rallly/icons";
|
||||||
import { cn } from "@rallly/ui";
|
import { cn } from "@rallly/ui";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
@ -116,7 +117,16 @@ const Clock = () => {
|
||||||
|
|
||||||
const MainNav = () => {
|
const MainNav = () => {
|
||||||
return (
|
return (
|
||||||
<div className="border-b bg-gray-50/50">
|
<m.div
|
||||||
|
variants={{
|
||||||
|
hidden: { y: -56, opacity: 0, height: 0 },
|
||||||
|
visible: { y: 0, opacity: 1, height: "auto" },
|
||||||
|
}}
|
||||||
|
initial={"hidden"}
|
||||||
|
animate="visible"
|
||||||
|
exit={"hidden"}
|
||||||
|
className="border-b bg-gray-50/50"
|
||||||
|
>
|
||||||
<Container className="flex h-14 items-center justify-between gap-4">
|
<Container className="flex h-14 items-center justify-between gap-4">
|
||||||
<div className="flex shrink-0">
|
<div className="flex shrink-0">
|
||||||
<Logo />
|
<Logo />
|
||||||
|
@ -142,20 +152,37 @@ const MainNav = () => {
|
||||||
<UserDropdown />
|
<UserDropdown />
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</m.div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StandardLayout: React.FunctionComponent<{
|
export const StandardLayout: React.FunctionComponent<{
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}> = ({ children, ...rest }) => {
|
hideNav?: boolean;
|
||||||
|
}> = ({ children, hideNav, ...rest }) => {
|
||||||
|
const key = hideNav ? "no-nav" : "nav";
|
||||||
return (
|
return (
|
||||||
<UserProvider>
|
<UserProvider>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<ModalProvider>
|
<ModalProvider>
|
||||||
<div className="flex min-h-screen flex-col" {...rest}>
|
<div className="flex min-h-screen flex-col" {...rest}>
|
||||||
<MainNav />
|
<AnimatePresence initial={false}>
|
||||||
<div>{children}</div>
|
{!hideNav ? <MainNav /> : null}
|
||||||
|
</AnimatePresence>
|
||||||
|
<AnimatePresence mode="wait" initial={false}>
|
||||||
|
<m.div
|
||||||
|
key={key}
|
||||||
|
variants={{
|
||||||
|
hidden: { opacity: 0, y: -56 },
|
||||||
|
visible: { opacity: 1, y: 0 },
|
||||||
|
}}
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit={{ opacity: 0, y: 56 }}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</m.div>
|
||||||
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
{process.env.NEXT_PUBLIC_FEEDBACK_EMAIL ? <FeedbackButton /> : null}
|
{process.env.NEXT_PUBLIC_FEEDBACK_EMAIL ? <FeedbackButton /> : null}
|
||||||
</ModalProvider>
|
</ModalProvider>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { cn } from "@rallly/ui";
|
import { cn } from "@rallly/ui";
|
||||||
|
import { m } from "framer-motion";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { Container } from "@/components/container";
|
import { Container } from "@/components/container";
|
||||||
|
@ -11,13 +12,15 @@ export const TopBar = (
|
||||||
}>,
|
}>,
|
||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<m.div
|
||||||
|
initial={{ y: 0 }}
|
||||||
|
exit={{ y: -100 }}
|
||||||
className={cn(
|
className={cn(
|
||||||
"sticky top-0 z-20 border-b bg-gray-50/75 py-3 backdrop-blur-md",
|
"sticky top-0 z-20 border-b bg-gray-50/75 py-3 backdrop-blur-md",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Container className={cn(props.className)}>{props.children}</Container>
|
<Container className={cn(props.className)}>{props.children}</Container>
|
||||||
</div>
|
</m.div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +34,7 @@ export const TopBarTitle = ({
|
||||||
return (
|
return (
|
||||||
<div className="flex h-9 min-w-0 items-center gap-2.5">
|
<div className="flex h-9 min-w-0 items-center gap-2.5">
|
||||||
{/* <Icon className="-ml-0.5 h-6 w-6 shrink-0" /> */}
|
{/* <Icon className="-ml-0.5 h-6 w-6 shrink-0" /> */}
|
||||||
<div className="truncate font-medium">{title}</div>
|
<div className="truncate font-medium tracking-tight">{title}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
import { trpc } from "@rallly/backend";
|
import { trpc } from "@rallly/backend";
|
||||||
import { withSessionSsr } from "@rallly/backend/next";
|
|
||||||
import { CheckCircleIcon } from "@rallly/icons";
|
import { CheckCircleIcon } from "@rallly/icons";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { GetServerSideProps } from "next";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { Trans, useTranslation } from "next-i18next";
|
import { Trans, useTranslation } from "next-i18next";
|
||||||
import { useMount } from "react-use";
|
import { useMount } from "react-use";
|
||||||
|
|
||||||
import { AuthLayout } from "@/components/layouts/auth-layout";
|
import { AuthLayout } from "@/components/layouts/auth-layout";
|
||||||
|
import { StandardLayout } from "@/components/layouts/standard-layout";
|
||||||
import { Spinner } from "@/components/spinner";
|
import { Spinner } from "@/components/spinner";
|
||||||
import { withSession } from "@/components/user-provider";
|
import { NextPageWithLayout } from "@/types";
|
||||||
import { usePostHog } from "@/utils/posthog";
|
import { usePostHog } from "@/utils/posthog";
|
||||||
import { withPageTranslations } from "@/utils/with-page-translations";
|
import { getStaticTranslations } from "@/utils/with-page-translations";
|
||||||
|
|
||||||
const defaultRedirectPath = "/polls";
|
const defaultRedirectPath = "/polls";
|
||||||
|
|
||||||
export const Page = () => {
|
const Page: NextPageWithLayout = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -76,8 +75,10 @@ export const Page = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withSession(Page);
|
Page.getLayout = (page) => {
|
||||||
|
return <StandardLayout hideNav={true}>{page}</StandardLayout>;
|
||||||
|
};
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = withSessionSsr(
|
export default Page;
|
||||||
withPageTranslations(),
|
|
||||||
);
|
export const getStaticProps = getStaticTranslations;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Loader2Icon } from "@rallly/icons";
|
import { Loader2Icon } from "@rallly/icons";
|
||||||
import { NextPage } from "next";
|
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
|
@ -7,17 +6,20 @@ import React from "react";
|
||||||
|
|
||||||
import { AuthLayout } from "@/components/auth/auth-layout";
|
import { AuthLayout } from "@/components/auth/auth-layout";
|
||||||
import { LoginForm } from "@/components/auth/login-form";
|
import { LoginForm } from "@/components/auth/login-form";
|
||||||
|
import { StandardLayout } from "@/components/layouts/standard-layout";
|
||||||
import { PageDialog } from "@/components/page-dialog";
|
import { PageDialog } from "@/components/page-dialog";
|
||||||
import { useWhoAmI } from "@/contexts/whoami";
|
import { useWhoAmI } from "@/contexts/whoami";
|
||||||
|
import { NextPageWithLayout } from "@/types";
|
||||||
|
|
||||||
import { getStaticTranslations } from "../utils/with-page-translations";
|
import { getStaticTranslations } from "../utils/with-page-translations";
|
||||||
|
|
||||||
const Redirect = () => {
|
const Redirect = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [redirect] = React.useState(router.query.redirect as string);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
router.replace((router.query.redirect as string) ?? "/");
|
router.replace(redirect ?? "/");
|
||||||
});
|
}, [router, redirect]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageDialog>
|
<PageDialog>
|
||||||
|
@ -26,7 +28,7 @@ const Redirect = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Page: NextPage<{ referer: string | null }> = () => {
|
const Page: NextPageWithLayout<{ referer: string | null }> = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const whoami = useWhoAmI();
|
const whoami = useWhoAmI();
|
||||||
|
|
||||||
|
@ -46,6 +48,10 @@ const Page: NextPage<{ referer: string | null }> = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Page.getLayout = (page) => {
|
||||||
|
return <StandardLayout hideNav={true}>{page}</StandardLayout>;
|
||||||
|
};
|
||||||
|
|
||||||
export default Page;
|
export default Page;
|
||||||
|
|
||||||
export const getStaticProps = getStaticTranslations;
|
export const getStaticProps = getStaticTranslations;
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import { NextPage } from "next";
|
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
|
|
||||||
|
import { StandardLayout } from "@/components/layouts/standard-layout";
|
||||||
|
import { NextPageWithLayout } from "@/types";
|
||||||
|
|
||||||
import { AuthLayout } from "../components/auth/auth-layout";
|
import { AuthLayout } from "../components/auth/auth-layout";
|
||||||
import { RegisterForm } from "../components/auth/login-form";
|
import { RegisterForm } from "../components/auth/login-form";
|
||||||
import { getStaticTranslations } from "../utils/with-page-translations";
|
import { getStaticTranslations } from "../utils/with-page-translations";
|
||||||
|
|
||||||
const Page: NextPage = () => {
|
const Page: NextPageWithLayout = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -25,6 +27,10 @@ const Page: NextPage = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Page.getLayout = (page) => {
|
||||||
|
return <StandardLayout hideNav={true}>{page}</StandardLayout>;
|
||||||
|
};
|
||||||
|
|
||||||
export const getStaticProps = getStaticTranslations;
|
export const getStaticProps = getStaticTranslations;
|
||||||
|
|
||||||
export default Page;
|
export default Page;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue