Skip to content

Commit 739afee

Browse files
✨ melhorando o carregamento da pagina com ssr
1 parent 6f35e17 commit 739afee

File tree

9 files changed

+111
-98
lines changed

9 files changed

+111
-98
lines changed

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SANITY_PROJECT_ID= #string
2+
SANITY_DATA_SET= #string
3+
SANITY_USE_CDN= #boolean

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
},
1414
"dependencies": {
1515
"@hookform/resolvers": "^3.6.0",
16+
"@portabletext/react": "^3.1.0",
1617
"@sanity/client": "^6.20.1",
1718
"@types/node": "20.14.5",
1819
"@types/react": "18.3.3",

src/app/artigos/Article.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ export interface Article {
66
description: string
77
author: string
88
createdAt: string
9+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
10+
body: any
911
}

src/app/artigos/ArticlesContent.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use client'
2+
3+
import { useState } from 'react'
4+
import { Article } from './Article'
5+
import { ArticleList } from './ArticleList'
6+
import { EmptyState } from './EmptyState'
7+
import { SeachInputField, SearchForm } from './SeachInputField'
8+
9+
interface ArticlesContentProps {
10+
articles: Article[]
11+
}
12+
13+
export function ArticlesContent(props: ArticlesContentProps) {
14+
const { articles: allArticles } = props
15+
const [articles, setArticles] = useState(allArticles)
16+
17+
function submitActionHandler(search: SearchForm) {
18+
if (search.query.length === 0) {
19+
setArticles(allArticles)
20+
} else {
21+
setArticles(
22+
allArticles.filter((article) => {
23+
const searchLower = search.query.toLowerCase()
24+
return (
25+
article.title.toLowerCase().includes(searchLower) ||
26+
article.description.toLowerCase().includes(searchLower) ||
27+
article.author.toLowerCase().includes(searchLower)
28+
)
29+
}),
30+
)
31+
}
32+
}
33+
34+
function ListStateManager() {
35+
if (articles.length === 0) {
36+
return <EmptyState />
37+
}
38+
39+
return <ArticleList articles={articles} />
40+
}
41+
42+
return (
43+
<>
44+
<div className="text-center grid gap-6 max-w-md mx-auto">
45+
<h2 className="font-bold text-4xl">Nossos artigos</h2>
46+
<p className="max-sm:mx-4">
47+
Aqui você econtra nossos artigos, onde trazemos os conhecimentos, para
48+
a comunidade.
49+
</p>
50+
<SeachInputField onSubmit={submitActionHandler} />
51+
</div>
52+
53+
<div className="h-[2px] bg-gray-600 mx-2 my-6" />
54+
55+
<div className="mt-16">
56+
<ListStateManager />
57+
</div>
58+
</>
59+
)
60+
}

src/app/artigos/SanityArticlesRepository.ts

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ export class SanityArticlesRepository implements ArticlesRepository {
1919
current: z.string(),
2020
}),
2121
publishedAt: z.string(),
22+
body: z.any(),
2223
})
2324

2425
async findMany(): Promise<Article[]> {
25-
const articleResponseSchema = z.array(this.articleSchema)
26-
const CONTENT_QUERY = `*[_type == "post"] {
26+
const articlesSchema = z.array(this.articleSchema)
27+
const query = `*[_type == "post"] {
2728
...,
2829
author->,
2930
mainImage {
@@ -34,23 +35,9 @@ export class SanityArticlesRepository implements ArticlesRepository {
3435
body
3536
}
3637
`
37-
const contentResponse = await client.fetch(CONTENT_QUERY)
38-
console.log(contentResponse)
39-
const articlesResponse = articleResponseSchema.parse(contentResponse)
40-
return articlesResponse.map((article) => {
41-
return {
42-
id: article.slug.current,
43-
title: article.title,
44-
description:
45-
article.description.length > 120
46-
? article.description.substring(0, 120).concat('...')
47-
: article.description,
48-
author: article.author.name,
49-
createdAt: article.publishedAt,
50-
imageUrl: 'https://cdn.sanity.io/'.concat(article.mainImage.asset.path),
51-
slug: article.slug.current,
52-
} as Article
53-
})
38+
const contentResponse = await client.fetch(query)
39+
const articlesResponse = articlesSchema.parse(contentResponse)
40+
return articlesResponse.map(this.map)
5441
}
5542

5643
async findBySlug(slug: string) {
@@ -65,27 +52,24 @@ export class SanityArticlesRepository implements ArticlesRepository {
6552
body
6653
}`
6754

68-
const params = { slug }
55+
const contentResponse = await client.fetch(query, { slug })
56+
const article = this.articleSchema.parse(contentResponse)
57+
return this.map(article)
58+
}
6959

70-
try {
71-
const contentResponse = await client.fetch(query, params)
72-
console.log('Artigo:', contentResponse)
73-
const article = this.articleSchema.parse(contentResponse)
74-
return {
75-
id: article.slug.current,
76-
title: article.title,
77-
description:
78-
article.description.length > 120
79-
? article.description.substring(0, 120).concat('...')
80-
: article.description,
81-
author: article.author.name,
82-
createdAt: article.publishedAt,
83-
imageUrl: 'https://cdn.sanity.io/'.concat(article.mainImage.asset.path),
84-
slug: article.slug.current,
85-
} as Article
86-
} catch (error) {
87-
console.error('Erro ao buscar artigo:', error)
88-
return null
60+
private map(article: z.infer<typeof this.articleSchema>) {
61+
return {
62+
id: article.slug.current,
63+
title: article.title,
64+
description:
65+
article.description.length > 120
66+
? article.description.substring(0, 120).concat('...')
67+
: article.description,
68+
author: article.author.name,
69+
createdAt: article.publishedAt,
70+
imageUrl: 'https://cdn.sanity.io/'.concat(article.mainImage.asset.path),
71+
slug: article.slug.current,
72+
body: article.body,
8973
}
9074
}
9175
}

src/app/artigos/[slug]/page.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import Image from 'next/image'
22
import { articlesRepository } from '../SanityArticlesRepository'
33

4+
import { PortableText } from '@portabletext/react'
5+
import { ArrowLeft } from 'lucide-react'
6+
import Link from 'next/link'
7+
48
interface ArticlePageProps {
59
params: {
610
slug: string
@@ -13,16 +17,23 @@ export default async function ArticlePage(props: ArticlePageProps) {
1317
if (!article) return <div>Not found</div>
1418

1519
return (
16-
<div className="max-w-4xl mx-auto mt-8 max-md:mx-4">
20+
<div className="max-w-4xl mx-auto mt-8 max-md:mx-4 grid gap-2">
21+
<Link
22+
href="/artigos"
23+
className="flex gap-2 items-center py-2 cursor-pointer"
24+
>
25+
<ArrowLeft /> Voltar
26+
</Link>
1727
<div className="grid items-center gap-4">
1828
<Image
19-
width={2200}
20-
height={120}
29+
width={1200}
30+
height={80}
2131
src={article.imageUrl}
2232
alt=""
2333
className="rounded-3xl"
2434
/>
2535
<h1 className="font-bold text-3xl">{article.title}</h1>
36+
<PortableText value={article.body} />
2637
</div>
2738
</div>
2839
)

src/app/artigos/page.tsx

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,12 @@
1-
'use client'
2-
3-
import { useEffect, useState } from 'react'
4-
import { Article } from './Article'
5-
import { ArticleList } from './ArticleList'
6-
import { EmptyState } from './EmptyState'
1+
import { ArticlesContent } from './ArticlesContent'
72
import { articlesRepository } from './SanityArticlesRepository'
8-
import { SeachInputField, SearchForm } from './SeachInputField'
9-
10-
export default function ArticlePage() {
11-
const [allArticles, setAllArticles] = useState<Article[]>([])
12-
const [articles, setArticles] = useState(allArticles)
13-
14-
useEffect(() => {
15-
articlesRepository.findMany().then((articles) => {
16-
setAllArticles(articles)
17-
setArticles(articles)
18-
})
19-
}, [setAllArticles, setArticles])
203

21-
function submitActionHandler(search: SearchForm) {
22-
if (search.query.length === 0) {
23-
setArticles(allArticles)
24-
} else {
25-
setArticles(
26-
allArticles.filter((article) => {
27-
const searchLower = search.query.toLowerCase()
28-
return (
29-
article.title.toLowerCase().includes(searchLower) ||
30-
article.description.toLowerCase().includes(searchLower) ||
31-
article.author.toLowerCase().includes(searchLower)
32-
)
33-
}),
34-
)
35-
}
36-
}
4+
export default async function ArticlePage() {
5+
const articles = await articlesRepository.findMany()
376

387
return (
398
<div className="my-12 md:px-8">
40-
<div className="text-center grid gap-6 max-w-md mx-auto">
41-
<h2 className="font-bold text-4xl">Nossos artigos</h2>
42-
<p className="max-sm:mx-4">
43-
Aqui você econtra nossos artigos, onde trazemos os conhecimentos, para
44-
a comunidade.
45-
</p>
46-
<SeachInputField onSubmit={submitActionHandler} />
47-
</div>
48-
49-
<div className="h-[2px] bg-gray-600 mx-2 my-6" />
50-
51-
<div className="mt-16">
52-
{articles.length === 0 ? (
53-
<EmptyState />
54-
) : (
55-
<ArticleList articles={articles} />
56-
)}
57-
</div>
9+
<ArticlesContent articles={articles} />
5810
</div>
5911
)
6012
}

src/utils/sanity/client.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { createClient } from '@sanity/client'
22

33
export const client = createClient({
4-
projectId: 'y8jhl6zw',
5-
dataset: 'production',
4+
projectId: process.env.SANITY_PROJECT_ID,
5+
dataset: process.env.SANITY_DATA_SET,
66
apiVersion: '2024-03-11',
7-
// Set to `true` for production environments
8-
useCdn: false,
7+
useCdn: process.env.SANITY_USE_CDN === 'true',
98
})

0 commit comments

Comments
 (0)