♻️ Prefetch subscription data + Upgrade framer motion (#1647)

This commit is contained in:
Luke Vella 2025-03-29 10:30:05 +00:00 committed by GitHub
parent 4dd2e69481
commit 8953cecd40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 749 additions and 1394 deletions

View file

@ -11,6 +11,7 @@ import {
} from "@rallly/ui/dropdown-menu";
import { Analytics } from "@vercel/analytics/react";
import { ChevronRightIcon, MenuIcon } from "lucide-react";
import { domAnimation, LazyMotion } from "motion/react";
import type { Viewport } from "next";
import Image from "next/image";
import Link from "next/link";
@ -44,112 +45,118 @@ export default async function Root({
return (
<html lang={locale} className={sans.className}>
<body>
<I18nProvider locale={locale}>
<div className="mx-auto flex min-h-full w-full max-w-7xl flex-col space-y-12 p-4 sm:p-8">
<header className="flex w-full items-center">
<div className="flex grow items-center gap-x-12">
<Link className="inline-block rounded" href="/">
<Image
src="/logo.svg"
width={130}
height={30}
alt="rallly.co"
/>
</Link>
<nav className="hidden items-center space-x-8 lg:flex">
<NavLink href="https://support.rallly.co/workflow/create">
<Trans t={t} i18nKey="howItWorks" defaults="How it Works" />
</NavLink>
<NavLink href="/pricing">
<Trans t={t} i18nKey="pricing" />
</NavLink>
<NavLink href="/blog">
<Trans t={t} i18nKey="blog" />
</NavLink>
<NavLink href="https://support.rallly.co">
<Trans t={t} i18nKey="support" />
</NavLink>
</nav>
</div>
<div className="flex items-center gap-4 sm:gap-8">
<Link
href={linkToApp("/login")}
className="hover:text-primary text-muted-foreground hidden rounded text-sm font-medium hover:no-underline hover:underline-offset-2 lg:inline-flex"
>
<Trans t={t} i18nKey="login" defaults="Login" />
</Link>
<Link
href={linkToApp()}
className="bg-primary hover:bg-primary-500 active:bg-primary-700 group inline-flex items-center gap-1 rounded-full py-1.5 pl-4 pr-3 text-sm font-medium text-white shadow-sm transition-transform"
>
<span>
<Trans t={t} i18nKey="goToApp" defaults="Go to app" />
</span>
<ChevronRightIcon className="inline-block size-4 transition-all group-active:translate-x-1" />
</Link>
<div className="flex items-center justify-center lg:hidden">
<DropdownMenu>
<DropdownMenuTrigger>
<MenuIcon className="size-6" />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" sideOffset={16}>
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href="https://support.rallly.co/workflow/create"
>
<Trans
t={t}
i18nKey="howItWorks"
defaults="How it Works"
/>
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href="/pricing"
>
<Trans t={t} i18nKey="pricing" defaults="Pricing" />
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href="/blog"
>
<Trans t={t} i18nKey="blog" />
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href="https://support.rallly.co"
>
<Trans t={t} i18nKey="support" />
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href={linkToApp("/login")}
>
<Trans t={t} i18nKey="login" defaults="Login" />
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<LazyMotion features={domAnimation}>
<I18nProvider locale={locale}>
<div className="mx-auto flex min-h-full w-full max-w-7xl flex-col space-y-12 p-4 sm:p-8">
<header className="flex w-full items-center">
<div className="flex grow items-center gap-x-12">
<Link className="inline-block rounded" href="/">
<Image
src="/logo.svg"
width={130}
height={30}
alt="rallly.co"
/>
</Link>
<nav className="hidden items-center space-x-8 lg:flex">
<NavLink href="https://support.rallly.co/workflow/create">
<Trans
t={t}
i18nKey="howItWorks"
defaults="How it Works"
/>
</NavLink>
<NavLink href="/pricing">
<Trans t={t} i18nKey="pricing" />
</NavLink>
<NavLink href="/blog">
<Trans t={t} i18nKey="blog" />
</NavLink>
<NavLink href="https://support.rallly.co">
<Trans t={t} i18nKey="support" />
</NavLink>
</nav>
</div>
</div>
</header>
<section className="relative grow">{children}</section>
<hr className="border-transparent" />
<footer>
<Footer />
</footer>
</div>
</I18nProvider>
<div className="flex items-center gap-4 sm:gap-8">
<Link
href={linkToApp("/login")}
className="hover:text-primary text-muted-foreground hidden rounded text-sm font-medium hover:no-underline hover:underline-offset-2 lg:inline-flex"
>
<Trans t={t} i18nKey="login" defaults="Login" />
</Link>
<Link
href={linkToApp()}
className="bg-primary hover:bg-primary-500 active:bg-primary-700 group inline-flex items-center gap-1 rounded-full py-1.5 pl-4 pr-3 text-sm font-medium text-white shadow-sm transition-transform"
>
<span>
<Trans t={t} i18nKey="goToApp" defaults="Go to app" />
</span>
<ChevronRightIcon className="inline-block size-4 transition-all group-active:translate-x-1" />
</Link>
<div className="flex items-center justify-center lg:hidden">
<DropdownMenu>
<DropdownMenuTrigger>
<MenuIcon className="size-6" />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" sideOffset={16}>
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href="https://support.rallly.co/workflow/create"
>
<Trans
t={t}
i18nKey="howItWorks"
defaults="How it Works"
/>
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href="/pricing"
>
<Trans t={t} i18nKey="pricing" defaults="Pricing" />
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href="/blog"
>
<Trans t={t} i18nKey="blog" />
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href="https://support.rallly.co"
>
<Trans t={t} i18nKey="support" />
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link
className="flex items-center gap-3 p-2 text-lg"
href={linkToApp("/login")}
>
<Trans t={t} i18nKey="login" defaults="Login" />
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</header>
<section className="relative grow">{children}</section>
<hr className="border-transparent" />
<footer>
<Footer />
</footer>
</div>
</I18nProvider>
</LazyMotion>
<Analytics />
</body>
</html>

View file

@ -1,6 +1,6 @@
"use client";
import { cn } from "@rallly/ui";
import { motion } from "framer-motion";
import * as m from "motion/react-m";
export const BonusItem = ({
className,
@ -13,7 +13,7 @@ export const BonusItem = ({
icon: React.ReactNode;
}>) => {
return (
<motion.div
<m.div
transition={{
delay,
type: "spring",
@ -32,6 +32,6 @@ export const BonusItem = ({
</span>
<div className="text-sm font-semibold">{children}</div>
</div>
</motion.div>
</m.div>
);
};

View file

@ -2,8 +2,8 @@
import { cn } from "@rallly/ui";
import { Badge } from "@rallly/ui/badge";
import { Button } from "@rallly/ui/button";
import { motion } from "framer-motion";
import { ChevronRightIcon } from "lucide-react";
import * as m from "motion/react-m";
import Image from "next/image";
import Link from "next/link";
import * as React from "react";
@ -17,7 +17,7 @@ const Screenshot = () => {
return (
<>
<motion.div
<m.div
transition={{
delay: 0.5,
type: "spring",
@ -42,8 +42,8 @@ const Screenshot = () => {
<span className="absolute left-1/2 top-full z-10 h-8 w-px -translate-x-1/2 bg-gray-800" />
<span className="absolute -bottom-12 left-1/2 z-10 inline-block size-3 origin-right -translate-x-1/2 rounded-full bg-gray-800 ring-1 ring-gray-800 ring-offset-2" />
<span className="absolute -bottom-12 left-1/2 z-10 inline-block size-3 origin-right -translate-x-1/2 animate-ping rounded-full bg-gray-800 ring-1 ring-gray-800 ring-offset-2" />
</motion.div>
<motion.div
</m.div>
<m.div
transition={{
type: "spring",
duration: 1,
@ -67,7 +67,7 @@ const Screenshot = () => {
setIsLoaded(true);
}}
/>
</motion.div>
</m.div>
</>
);
};

View file

@ -1,6 +1,6 @@
"use client";
import { motion } from "framer-motion";
import { ArrowUpRight } from "lucide-react";
import * as m from "motion/react-m";
import Image from "next/image";
import Link from "next/link";
import React from "react";
@ -157,7 +157,7 @@ const Mention = ({
delay?: number;
}>) => {
return (
<motion.div
<m.div
transition={{
delay,
type: "spring",
@ -170,7 +170,7 @@ const Mention = ({
>
<div className="flex items-start justify-between">{logo}</div>
<p className="grow text-center text-base">{children}</p>
</motion.div>
</m.div>
);
};
@ -257,7 +257,7 @@ export const MentionedBy = () => {
export const BigTestimonial = () => {
return (
<motion.div
<m.div
transition={{
duration: 1,
type: "spring",
@ -310,7 +310,7 @@ export const BigTestimonial = () => {
</div>
</div>
</div>
</motion.div>
</m.div>
);
};

View file

@ -68,6 +68,7 @@
"lodash": "^4.17.21",
"lucide-react": "^0.387.0",
"micro": "^10.0.1",
"motion": "^12.6.2",
"nanoid": "^5.0.9",
"next-auth": "^5.0.0-beta.25",
"php-serialize": "^4.1.1",

View file

@ -1,15 +1,25 @@
import "tailwindcss/tailwind.css";
import "../../style.css";
import { PostHogProvider } from "@rallly/posthog/client";
import { Toaster } from "@rallly/ui/toaster";
import type { Metadata, Viewport } from "next";
import { TooltipProvider } from "@rallly/ui/tooltip";
import { dehydrate, Hydrate } from "@tanstack/react-query";
import { domAnimation, LazyMotion } from "motion/react";
import type { Viewport } from "next";
import { Inter } from "next/font/google";
import { SessionProvider } from "next-auth/react";
import React from "react";
import { TimeZoneChangeDetector } from "@/app/[locale]/timezone-change-detector";
import { Providers } from "@/app/providers";
import { UserProvider } from "@/components/user-provider";
import { I18nProvider } from "@/i18n/client";
import { auth } from "@/next-auth";
import { TRPCProvider } from "@/trpc/client/provider";
import { createSSRHelper } from "@/trpc/server/create-ssr-helper";
import { ConnectedDayjsProvider } from "@/utils/dayjs";
import { PostHogPageView } from "../posthog-page-view";
const inter = Inter({
subsets: ["latin"],
@ -29,25 +39,35 @@ export default async function Root({
params: { locale: string };
}) {
const session = await auth();
const trpc = await createSSRHelper();
await trpc.user.subscription.prefetch();
return (
<html lang={locale} className={inter.className}>
<body>
<Toaster />
<SessionProvider session={session}>
<Providers>
{children}
<TimeZoneChangeDetector />
</Providers>
</SessionProvider>
<I18nProvider>
<TRPCProvider>
<Hydrate state={dehydrate(trpc.queryClient)}>
<LazyMotion features={domAnimation}>
<SessionProvider session={session}>
<PostHogProvider>
<PostHogPageView />
<TooltipProvider>
<UserProvider>
<ConnectedDayjsProvider>
{children}
<TimeZoneChangeDetector />
</ConnectedDayjsProvider>
</UserProvider>
</TooltipProvider>
</PostHogProvider>
</SessionProvider>
</LazyMotion>
</Hydrate>
</TRPCProvider>
</I18nProvider>
</body>
</html>
);
}
export const metadata: Metadata = {
title: {
template: "%s | Rallly",
default: "Rallly",
},
};

View file

@ -1,32 +0,0 @@
"use client";
import { PostHogProvider } from "@rallly/posthog/client";
import { TooltipProvider } from "@rallly/ui/tooltip";
import { domMax, LazyMotion } from "framer-motion";
import { UserProvider } from "@/components/user-provider";
import { I18nProvider } from "@/i18n/client";
import { TRPCProvider } from "@/trpc/client/provider";
import { ConnectedDayjsProvider } from "@/utils/dayjs";
import { PostHogPageView } from "./posthog-page-view";
export function Providers(props: { children: React.ReactNode }) {
return (
<LazyMotion features={domMax}>
<I18nProvider>
<PostHogProvider>
<PostHogPageView />
<TRPCProvider>
<TooltipProvider>
<UserProvider>
<ConnectedDayjsProvider>
{props.children}
</ConnectedDayjsProvider>
</UserProvider>
</TooltipProvider>
</TRPCProvider>
</PostHogProvider>
</I18nProvider>
</LazyMotion>
);
}

View file

@ -1,5 +1,6 @@
import { AnimatePresence, m } from "framer-motion";
import Cookies from "js-cookie";
import { AnimatePresence } from "motion/react";
import * as m from "motion/react-m";
import Link from "next/link";
import * as React from "react";
import { createPortal } from "react-dom";

View file

@ -5,8 +5,8 @@ import { Badge } from "@rallly/ui/badge";
import type { DialogProps } from "@rallly/ui/dialog";
import { Dialog, DialogContent, useDialog } from "@rallly/ui/dialog";
import { RadioGroup, RadioGroupItem } from "@rallly/ui/radio-group";
import { m } from "framer-motion";
import { CheckIcon } from "lucide-react";
import * as m from "motion/react-m";
import Link from "next/link";
import React from "react";

View file

@ -9,8 +9,9 @@ import {
SelectTrigger,
SelectValue,
} from "@rallly/ui/select";
import { AnimatePresence, m } from "framer-motion";
import { MoreHorizontalIcon, PlusIcon, UsersIcon } from "lucide-react";
import { AnimatePresence } from "motion/react";
import * as m from "motion/react-m";
import * as React from "react";
import smoothscroll from "smoothscroll-polyfill";

View file

@ -1,6 +1,7 @@
import { cn } from "@rallly/ui";
import { AnimatePresence, m } from "framer-motion";
import { User2Icon } from "lucide-react";
import { AnimatePresence } from "motion/react";
import * as m from "motion/react-m";
import * as React from "react";
import { usePrevious } from "react-use";

View file

@ -1,3 +1,5 @@
"use client";
import type { TimeFormat } from "@rallly/database";
import dayjs from "dayjs";
import advancedFormat from "dayjs/plugin/advancedFormat";

View file

@ -43,7 +43,6 @@
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
"dotenv-cli": "^7.1.0",
"framer-motion": "^10.16.4",
"next": "^14.2.25",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.3",

View file

@ -19,7 +19,7 @@
"@react-email/render": "^0.0.12",
"@vercel/functions": "*",
"nodemailer": "^6.9.9",
"react-email": "^2.0.0"
"react-email": "^4.0.2"
},
"devDependencies": {
"@rallly/tailwind-config": "*",

View file

@ -1,2 +1,4 @@
"use client";
export { PostHogProvider } from "./provider";
export { usePostHog } from "posthog-js/react";

1799
yarn.lock

File diff suppressed because it is too large Load diff