diff --git a/app/(home-pages)/p/[didOrHandle]/PubListing.tsx b/app/(home-pages)/p/[didOrHandle]/PubListing.tsx index e95e215e..e948a047 100644 --- a/app/(home-pages)/p/[didOrHandle]/PubListing.tsx +++ b/app/(home-pages)/p/[didOrHandle]/PubListing.tsx @@ -8,7 +8,20 @@ import { BaseThemeProvider } from "components/ThemeManager/ThemeProvider"; import { blobRefToSrc } from "src/utils/blobRefToSrc"; import { timeAgo } from "src/utils/timeAgo"; -export const PubListing = (props: PublicationSubscription) => { +type PubListingProps = Omit< + PublicationSubscription, + | "publication_subscriptions" + | "publication_newsletter_settings" + | "documents_in_publications" +> & { + publication_subscriptions?: PublicationSubscription["publication_subscriptions"]; + publication_newsletter_settings?: PublicationSubscription["publication_newsletter_settings"]; + documents_in_publications?: PublicationSubscription["documents_in_publications"]; + showSubscribeButton?: boolean; + constrainHeight?: boolean; +}; + +export const PubListing = (props: PubListingProps) => { let record = props.record; let theme = usePubTheme(record?.theme); let backgroundImage = record?.theme?.backgroundImage?.image?.ref @@ -39,15 +52,21 @@ export const PubListing = (props: PublicationSubscription) => { >
-

{record.name}

+

+ {record.name} +

{record.description && ( -

+

{record.description}

)} @@ -55,26 +74,29 @@ export const PubListing = (props: PublicationSubscription) => {
{props.authorProfile?.handle}
-

- Updated{" "} - {timeAgo( - props.documents_in_publications?.[0]?.documents?.sort_date || - "", - )} -

-
-
- + {props.documents_in_publications?.[0]?.documents?.sort_date && ( +

+ Updated{" "} + {timeAgo( + props.documents_in_publications[0].documents.sort_date, + )} +

+ )}
+ {props.showSubscribeButton && ( +
+ +
+ )} diff --git a/app/(home-pages)/p/[didOrHandle]/subscriptions/SubscriptionsContent.tsx b/app/(home-pages)/p/[didOrHandle]/subscriptions/SubscriptionsContent.tsx index 917f2dc4..941edcde 100644 --- a/app/(home-pages)/p/[didOrHandle]/subscriptions/SubscriptionsContent.tsx +++ b/app/(home-pages)/p/[didOrHandle]/subscriptions/SubscriptionsContent.tsx @@ -83,7 +83,12 @@ export const ProfileSubscriptionsContent = (props: {
{allSubscriptions.map((sub) => ( - + ))}
{/* Trigger element for loading more subscriptions */} diff --git a/app/about/Examples.tsx b/app/about/Examples.tsx index 8d1cb55a..a5795cce 100644 --- a/app/about/Examples.tsx +++ b/app/about/Examples.tsx @@ -1,24 +1,84 @@ import { GoToArrow } from "components/Icons/GoToArrow"; +import { supabaseServerClient } from "supabase/serverClient"; +import { normalizePublicationRecord } from "src/utils/normalizeRecords"; +import { PubListing } from "app/(home-pages)/p/[didOrHandle]/PubListing"; +import { idResolver } from "app/(home-pages)/reader/idResolver"; + +const pubs = [ + "at://did:plc:e27b62phtzr3sjgs3zwdbctq/site.standard.publication/3lyevoglvs224", // zjsm.fm + "at://did:plc:b2p6rujcgpenbtcjposmjuc3/site.standard.publication/3m3axfv5hms24", // Cosmik Labs + "at://did:plc:x2xmijn2egk5g67u3cwkddzy/site.standard.publication/3m2avdoogvs2f", // Aaron Ross Powell's Blog + "at://did:plc:qsn6ihzsby2lr2r3sl4z3bgf/site.standard.publication/3lunssrkwqc27", // Eva's Garden + "at://did:plc:oyvx5qyivlj3s6fnbxpnadba/site.standard.publication/3m3bgolkrvs2c", // Cat Café + "at://did:plc:bsxmru6yec5sy42azm7cnrqq/site.standard.publication/3lwk77r5y422r", // leaf litter + "at://did:plc:2zmxikig2sj7gqaezl5gntae/site.standard.publication/3lusxwydhqs2i", // How Streamplace Works + "at://did:plc:jl5dgp7xb34xfqlpywt7kcp5/site.standard.publication/3lx4aluuanc27", // hyper girl shares hyperlinks + + "at://did:plc:7kjkqt7amna7pih3lcvpf7g2/site.standard.publication/3lptkwbkdws2l", // Dreaming at the Edge of the Apocalypse + "at://did:plc:lulmyldiq4sb2ikags5sfb25/site.standard.publication/3lw5apjilmc2v", // microcosm + "at://did:plc:mdjhvva6vlrswsj26cftjttd/site.standard.publication/3lwyzotjqu22i", // Connected Places +]; + +async function getExamplePub(uri: string) { + const { data: publications } = await supabaseServerClient + .from("publications") + .select("*") + .eq("uri", uri) + .limit(1); + const publication = publications?.[0]; + if (!publication) return null; + const record = normalizePublicationRecord(publication.record); + if (!record) return null; + const id = await idResolver.did.resolve(publication.identity_did); + const authorProfile = id?.alsoKnownAs?.[0] + ? { handle: `@${id.alsoKnownAs[0].slice(5)}` } + : undefined; + return { uri: publication.uri, record, authorProfile }; +} + +export const Examples = async () => { + const examplePubs = (await Promise.all(pubs.map(getExamplePub))).filter( + (pub): pub is NonNullable => pub !== null, + ); + + const pubsWithMargins = examplePubs.map((pub) => ({ + ...pub, + topMargin: `${Math.floor(Math.random() * 6) * 10}px`, + })); + + const renderPub = ( + pub: (typeof pubsWithMargins)[number], + keySuffix: string, + ) => ( +
+
+ +
+ ); -export const Examples = () => { return ( -
+

Loved by thousands of writers

Explore More

-
-
-
-
-
-
{" "} -
-
-
-
-
+
+
+ {pubsWithMargins.map((pub) => renderPub(pub, "orig"))} + {pubsWithMargins.map((pub) => renderPub(pub, "dup"))} +
); diff --git a/app/about/Features.tsx b/app/about/Features.tsx index c27c806f..15f52371 100644 --- a/app/about/Features.tsx +++ b/app/about/Features.tsx @@ -4,9 +4,10 @@ export const Features = () => { return ( <>
-
-
-
+
+ {" "} +
+

Reach your readers

Send updates via email and on the Atmosphere, a social ecosystem @@ -14,28 +15,26 @@ export const Features = () => {

-
-
+
+

Express yourself

Custom themes and domains

-
+
-
+
-

Write and read together

+

Write together

- with collaborative editing
+ Collaborative editing
and easy sharing{" "}

-
+

Build your community

-

- Plan events, start conversations, and share everything everywhere -

+

Events, conversations, and easy sharing

diff --git a/app/about/Footer.tsx b/app/about/Footer.tsx index 9cd2a6ab..15842157 100644 --- a/app/about/Footer.tsx +++ b/app/about/Footer.tsx @@ -1,7 +1,7 @@ export const Footer = () => { return (
-
+
Explore diff --git a/app/about/LandingCTA.tsx b/app/about/LandingCTA.tsx index a3228e69..8ef74d27 100644 --- a/app/about/LandingCTA.tsx +++ b/app/about/LandingCTA.tsx @@ -34,21 +34,21 @@ export const LandingCTABottom = () => { <>

Write with Leaflet!

- + Get Started!

Pssst… Are you stuck on Substack?

-

+

Join the waitlist for our migration tools!

- + Join
diff --git a/app/about/Pricing.tsx b/app/about/Pricing.tsx index 58c320e4..097340b3 100644 --- a/app/about/Pricing.tsx +++ b/app/about/Pricing.tsx @@ -1,17 +1,39 @@ +"use client"; + import { ButtonPrimary } from "components/Buttons"; +import { ToggleGroup } from "components/ToggleGroup"; +import { useState } from "react"; export const Pricing = () => { + let [cadence, setCadence] = useState<"monthly" | "yearly">("yearly"); + return ( -
-

Pricing

-
-
-
- -
{" "} +
+

Pricing

+ +
+
+
+ +

Free

@@ -19,50 +41,85 @@ export const Pricing = () => {

Start Writing
-
    +
      +
    • Fast, powerful text editing
    • +
      +
    • Custom Themes and Domains
    • +
      + +
    • Publication Pages and Nav
    • +
      +
    • Unlimited Pubs and Posts
    • -
    • Atmosphere Subscriptions
    • -
    • Custom Themes
    • -
    • Custom Domains
    • +
      + +
    • Subscriptions via Atmosphere
    • +
      + +
    • Comments, Quoting, and Sharing
-
-
- +
+
+
-

$120/year

+

+ {cadence === "yearly" ? "$120/year" : "$12/month"} +

- Serious publishers need serious tools + Serious publishers, serious tools

Get Pro
-
    +
    • Everything in Free
    • -
    • Analytics
    • +
      + +
    • +
      Analytics
      +
      + Subscriber count, page views, referrers +
      +
    • +
      +
    • 1k Email Subscribers
      $5/mo for every additional 1k
    • +
      + +
    • +
      Coming soon!
      +
      + Memberships, group publication,
      + social reader, and more +
      +
diff --git a/app/about/about.css b/app/about/about.css index d2696e6c..c6f4322d 100644 --- a/app/about/about.css +++ b/app/about/about.css @@ -28,6 +28,38 @@ .aboutPage p { @apply text-[1rem] sm:text-[1.25rem] md:text-[1.5rem]; } + +.pubAndPostCarousel p { + @apply text-[1rem]; +} +.pubAndPostCarousel h4 { + font-weight: 700; + + @apply text-[1.25rem]; +} + +.pubAndPostCarouselTrack { + animation: pubAndPostCarouselScroll 100s linear infinite; +} + +.pubAndPostCarousel:hover .pubAndPostCarouselTrack { + animation-play-state: paused; +} + +@media (prefers-reduced-motion: reduce) { + .pubAndPostCarouselTrack { + animation: none; + } +} + +@keyframes pubAndPostCarouselScroll { + from { + transform: translateX(0); + } + to { + transform: translateX(-50%); + } +} .aboutCover { }