diff --git a/app/api/rpc/[command]/route.ts b/app/api/rpc/[command]/route.ts index e41105ab..3d44b2b7 100644 --- a/app/api/rpc/[command]/route.ts +++ b/app/api/rpc/[command]/route.ts @@ -9,6 +9,7 @@ import { getFactsFromHomeLeaflets } from "./getFactsFromHomeLeaflets"; import { Vercel } from "@vercel/sdk"; import { get_domain_status } from "./domain_routes"; import { get_leaflet_data } from "./get_leaflet_data"; +import { get_publication_data } from "./get_publication_data"; const client = postgres(process.env.DB_URL as string, { idle_timeout: 5 }); let supabase = createClient( @@ -33,6 +34,7 @@ let Routes = [ getFactsFromHomeLeaflets, get_domain_status, get_leaflet_data, + get_publication_data, ]; export async function POST( req: Request, diff --git a/app/lish/PostList.tsx b/app/lish/PostList.tsx index 09d27dd1..23fba32a 100644 --- a/app/lish/PostList.tsx +++ b/app/lish/PostList.tsx @@ -1,11 +1,8 @@ "use client"; import Link from "next/link"; -import { Separator } from "components/Layout"; import { Json } from "supabase/database.types"; import { PubLeafletDocument } from "lexicons/api"; -import { ButtonPrimary } from "components/Buttons"; import { useIdentityData } from "components/IdentityProvider"; -import { usePublicationRelationship } from "./[handle]/[publication]/usePublicationRelationship"; import { useParams } from "next/navigation"; import { AtUri } from "@atproto/syntax"; diff --git a/app/lish/[handle]/[publication]/dashboard/DraftList.tsx b/app/lish/[handle]/[publication]/dashboard/DraftList.tsx index 52344ea9..f91eb8ec 100644 --- a/app/lish/[handle]/[publication]/dashboard/DraftList.tsx +++ b/app/lish/[handle]/[publication]/dashboard/DraftList.tsx @@ -1,31 +1,18 @@ "use client"; -import { usePublicationRelationship } from "../usePublicationRelationship"; -import { usePublicationContext } from "components/Providers/PublicationContext"; import Link from "next/link"; import { NewDraftSecondaryButton } from "./NewDraftButton"; -import { MoreOptionsTiny } from "components/Icons/MoreOptionsTiny"; -import { Menu, MenuItem } from "components/Layout"; -import { MoreOptionsVerticalTiny } from "components/Icons/MoreOptionsVerticalTiny"; -import { DeleteSmall } from "components/Icons/DeleteSmall"; import React from "react"; +import { usePublicationData } from "./PublicationSWRProvider"; -export function DraftList(props: { - publication: string; - drafts: { - leaflet: string; - description: string; - title: string; - }[]; -}) { - let rel = usePublicationRelationship(); - let { publication } = usePublicationContext(); - if (!publication) return null; - if (!rel?.isAuthor) return null; +export function DraftList() { + let pub_data = usePublicationData(); + console.log({ pub_data }); + if (!pub_data) return null; return (
- - {props.drafts.map((d) => { + + {pub_data.leaflets_in_publications.map((d) => { return ( diff --git a/app/lish/[handle]/[publication]/dashboard/PublicationSWRProvider.tsx b/app/lish/[handle]/[publication]/dashboard/PublicationSWRProvider.tsx new file mode 100644 index 00000000..d4a839da --- /dev/null +++ b/app/lish/[handle]/[publication]/dashboard/PublicationSWRProvider.tsx @@ -0,0 +1,41 @@ +"use client"; + +import type { GetPublicationDataReturnType } from "app/api/rpc/[command]/get_publication_data"; +import { callRPC } from "app/api/rpc/client"; +import { createContext, useContext } from "react"; +import useSWR, { SWRConfig } from "swr"; + +const PublicationContext = createContext({ name: "", did: "" }); +export function PublicationSWRDataProvider(props: { + publication_name: string; + publication_did: string; + publication_data: GetPublicationDataReturnType["result"]; + children: React.ReactNode; +}) { + return ( + + + {props.children} + + + ); +} + +export function usePublicationData() { + let { name, did } = useContext(PublicationContext); + let { data } = useSWR( + "publication-data", + async () => + (await callRPC("get_publication_data", { publication_name: name, did })) + ?.result, + ); + return data; +} diff --git a/app/lish/[handle]/[publication]/dashboard/PublishedPostsLists.tsx b/app/lish/[handle]/[publication]/dashboard/PublishedPostsLists.tsx new file mode 100644 index 00000000..a6a4d31f --- /dev/null +++ b/app/lish/[handle]/[publication]/dashboard/PublishedPostsLists.tsx @@ -0,0 +1,70 @@ +"use client"; +import Link from "next/link"; +import { AtUri } from "@atproto/syntax"; +import { PubLeafletDocument } from "lexicons/api"; +import { EditTiny } from "components/Icons/EditTiny"; +import { MoreOptionsVerticalTiny } from "components/Icons/MoreOptionsVerticalTiny"; +import { Menu, MenuItem } from "components/Layout"; + +import { usePublicationData } from "./PublicationSWRProvider"; +import { Fragment } from "react"; +import { useParams } from "next/navigation"; + +export function PublishedPostsList() { + let publication = usePublicationData(); + let params = useParams(); + if (!publication) return null; + if (publication.documents_in_publications.length === 0) + return ( +
+ Nothing's been published yet... +
+ ); + return ( +
+ {publication.documents_in_publications.map((doc) => { + if (!doc.documents) return null; + let leaflet = publication.leaflets_in_publications.find( + (l) => doc.documents && l.doc === doc.documents.uri, + ); + let uri = new AtUri(doc.documents.uri); + let record = doc.documents.data as PubLeafletDocument.Record; + + return ( + +
+ +

{record.title}

+ {record.description ? ( +

{record.description}

+ ) : null} + {record.publishedAt ? ( +

+ Published{" "} + {new Date(record.publishedAt).toLocaleDateString( + undefined, + { + year: "2-digit", + month: "long", + day: "2-digit", + }, + )} +

+ ) : null} + + {leaflet && ( + + + + )} +
+
+
+ ); + })} +
+ ); +} diff --git a/app/lish/[handle]/[publication]/dashboard/layout.tsx b/app/lish/[handle]/[publication]/dashboard/layout.tsx deleted file mode 100644 index 19dfe4a5..00000000 --- a/app/lish/[handle]/[publication]/dashboard/layout.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { IdResolver } from "@atproto/identity"; -import { PublicationContextProvider } from "components/Providers/PublicationContext"; -import { supabaseServerClient } from "supabase/serverClient"; - -const idResolver = new IdResolver(); -export default async function PublicationLayout(props: { - children: React.ReactNode; - params: Promise<{ - publication: string; - handle: string; - }>; -}) { - let did = await idResolver.handle.resolve((await props.params).handle); - if (!did) return <>{props.children}; - let { data: publication } = await supabaseServerClient - .from("publications") - .select( - "*, documents_in_publications(documents(*)), leaflets_in_publications(*, permission_tokens(*, permission_token_rights(*), custom_domain_routes!custom_domain_routes_edit_permission_token_fkey(*) ))", - ) - .eq("identity_did", did) - .eq("name", decodeURIComponent((await props.params).publication)) - .single(); - - if (!publication) return <>{props.children}; - return ( - - {props.children} - - ); -} diff --git a/app/lish/[handle]/[publication]/dashboard/page.tsx b/app/lish/[handle]/[publication]/dashboard/page.tsx index fa9fbbb0..8afb7147 100644 --- a/app/lish/[handle]/[publication]/dashboard/page.tsx +++ b/app/lish/[handle]/[publication]/dashboard/page.tsx @@ -11,14 +11,10 @@ import { DraftList } from "./DraftList"; import { getIdentityData } from "actions/getIdentityData"; import { ThemeProvider } from "components/ThemeManager/ThemeProvider"; import { Actions } from "./Actions"; -import Link from "next/link"; -import { AtUri } from "@atproto/syntax"; -import { PubLeafletDocument } from "lexicons/api"; import React from "react"; -import { EditTiny } from "components/Icons/EditTiny"; -import { MoreOptionsVerticalTiny } from "components/Icons/MoreOptionsVerticalTiny"; -import { Menu, MenuItem } from "components/Layout"; import { get_publication_data } from "app/api/rpc/[command]/get_publication_data"; +import { PublicationSWRDataProvider } from "./PublicationSWRProvider"; +import { PublishedPostsList } from "./PublishedPostsLists"; const idResolver = new IdResolver(); @@ -60,101 +56,40 @@ export default async function Publication(props: { try { return ( - -
-
-
- - - + + +
+
+
+ + + +
+
+ , + Published: , + }} + defaultTab={"Drafts"} + /> +
+ +
+ +
+
-
- !p.doc, - )} - /> - ), - Published: - publication.documents_in_publications.length === 0 ? ( -
- Nothing's been published yet... -
- ) : ( -
- {publication.documents_in_publications.map((doc) => { - if (!doc.documents) return null; - let leaflet = - publication.leaflets_in_publications.find( - (l) => - doc.documents && l.doc === doc.documents.uri, - ); - let uri = new AtUri(doc.documents.uri); - let record = doc.documents - .data as PubLeafletDocument.Record; - - return ( - -
- -

- {record.title} -

- {record.description ? ( -

- {record.description} -

- ) : null} - {record.publishedAt ? ( -

- Published{" "} - {new Date( - record.publishedAt, - ).toLocaleDateString(undefined, { - year: "2-digit", - month: "long", - day: "2-digit", - })} -

- ) : null} - - {leaflet && ( - - - - )} -
-
-
- ); - })} -
- ), - }} - defaultTab={"Drafts"} - /> -
- -
- -
-
-
- + + ); } catch (e) { console.log(e); diff --git a/app/lish/[handle]/[publication]/usePublicationRelationship.ts b/app/lish/[handle]/[publication]/usePublicationRelationship.ts deleted file mode 100644 index 3986ad13..00000000 --- a/app/lish/[handle]/[publication]/usePublicationRelationship.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { AtUri } from "@atproto/syntax"; -import { useIdentityData } from "components/IdentityProvider"; -import { usePublicationContext } from "components/Providers/PublicationContext"; - -export const usePublicationRelationship = () => { - let identity = useIdentityData(); - let publication = usePublicationContext(); - if (!publication.publication) return null; - let pubUri = new AtUri(publication.publication.uri); - let isAuthor = - identity.identity?.atp_did && pubUri.hostname === identity.identity.atp_did; - let isSubscribed = identity.identity?.subscribers_to_publications.find( - (p) => p.publication === publication.publication?.uri, - ); - return { isAuthor, isSubscribed }; -}; diff --git a/components/Providers/PublicationContext.tsx b/components/Providers/PublicationContext.tsx deleted file mode 100644 index d2fd0285..00000000 --- a/components/Providers/PublicationContext.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client"; -import { createContext, useContext, ReactNode } from "react"; - -interface PublicationContextType { - publication: { uri: string; name: string } | null; -} - -const PublicationContext = createContext( - undefined, -); - -export function PublicationContextProvider({ - children, - publication, -}: { - children: ReactNode; - publication: PublicationContextType["publication"]; -}) { - return ( - - {children} - - ); -} - -export function usePublicationContext() { - const context = useContext(PublicationContext); - if (context === undefined) { - throw new Error("usePublication must be used within a PublicationProvider"); - } - return context; -}