at main 3.4 kB view raw
1import { CardArticle } from '@/components/CardArticle/CardArticle'; 2import { Divider } from '@/components/Divider/Divider'; 3import { Heading } from '@/components/Heading/Heading'; 4import { Aside, Layout, Main } from '@/components/Layout/Layout'; 5import { Link } from '@/components/Link/Link'; 6import { Paragraph } from '@/components/Paragraph/Paragraph'; 7import TLDRProfile from '@/components/TLDRProfile/TLDRProfile'; 8import { useLeaflet } from '@/hooks/atproto'; 9import type { JSX } from 'react'; 10import { Helmet } from 'react-helmet-async'; 11 12/** 13 * Writing page component - displays blog posts from AT Protocol PDS 14 * 15 * @returns JSX element with writing page content 16 */ 17 18export default function WritingPage(): JSX.Element { 19 const { data: documents, loading, error } = useLeaflet(); 20 21 const jsonLd = { 22 '@context': 'https://schema.org', 23 '@type': 'CollectionPage', 24 name: 'Writing by Barry Prendergast', 25 description: 'Articles and writing on design strategy, product design, and design operations.', 26 url: 'https://renderg.host/writing', 27 author: { 28 '@type': 'Person', 29 name: 'Barry Prendergast', 30 url: 'https://renderg.host', 31 }, 32 }; 33 34 return ( 35 <> 36 <Helmet> 37 <title>Writing | Barry Prendergast</title> 38 <meta 39 name="description" 40 content="Articles and writing on design strategy, product design, and design operations by Barry Prendergast." 41 /> 42 <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} /> 43 </Helmet> 44 45 <Layout theme="default"> 46 <Main> 47 <div className="flex flex-col gap-12"> 48 <Heading level={2} size="md"> 49 writing / <Link href="/">renderg.host</Link> 50 </Heading> 51 52 <Paragraph size="lg">Thoughts on design strategy, product design, and building better products.</Paragraph> 53 54 {loading && <Paragraph size="lg">Loading posts...</Paragraph>} 55 56 {error && <Paragraph size="lg">Error loading posts: {error}</Paragraph>} 57 58 {!loading && !error && (!documents || documents.length === 0) && ( 59 <Paragraph size="lg">No posts found.</Paragraph> 60 )} 61 62 {!loading && !error && documents && documents.length > 0 && ( 63 <div className="grid grid-cols-1 border-2 border-bones-black-20 dark:border-bones-white-20"> 64 {documents.map((doc, index) => ( 65 <> 66 <CardArticle 67 key={doc.uri} 68 article={{ 69 title: doc.title, 70 subtitle: doc.description || '', 71 coverImage: '', 72 articleUrl: doc.articleUrl, 73 publication: doc.publication.name, 74 publicationIcon: doc.publication.icon, 75 published: doc.publishedAt, 76 }} 77 /> 78 {index < documents.length - 1 && <Divider />} 79 </> 80 ))} 81 </div> 82 )} 83 84 <Paragraph size="lg"> 85 <Link href="/"> Back to Home</Link> 86 </Paragraph> 87 </div> 88 </Main> 89 90 <Aside> 91 <TLDRProfile /> 92 </Aside> 93 </Layout> 94 </> 95 ); 96}