Skip to content

Commit b99b332

Browse files
✨ adicionando a pagina de artigos mockada
1 parent e2426fd commit b99b332

File tree

12 files changed

+427
-17
lines changed

12 files changed

+427
-17
lines changed

next.config.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
/** @type {import('next').NextConfig} */
2-
const nextConfig = {}
2+
const nextConfig = {
3+
images: {
4+
remotePatterns: [
5+
{
6+
protocol: 'https',
7+
hostname: 'images.unsplash.com',
8+
port: '',
9+
pathname: '/**',
10+
},
11+
],
12+
},
13+
}
314

415
module.exports = nextConfig

package-lock.json

Lines changed: 101 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,29 @@
1212
"test:2e2-report": "npx playwright show-report"
1313
},
1414
"dependencies": {
15+
"@hookform/resolvers": "^3.6.0",
1516
"@next/font": "^13.4.1",
1617
"@types/node": "20.1.0",
1718
"@types/react": "18.2.6",
1819
"@types/react-dom": "18.2.4",
1920
"autoprefixer": "10.4.14",
2021
"eslint": "8.40.0",
2122
"eslint-config-next": "13.4.1",
23+
"lodash.debounce": "^4.0.8",
2224
"lucide-react": "^0.383.0",
2325
"next": "13.4.1",
2426
"postcss": "8.4.23",
2527
"react": "18.2.0",
2628
"react-dom": "18.2.0",
29+
"react-hook-form": "^7.52.0",
2730
"react-icons": "^4.8.0",
2831
"tailwindcss": "3.3.2",
29-
"typescript": "5.0.4"
32+
"typescript": "5.0.4",
33+
"zod": "^3.23.8"
3034
},
3135
"devDependencies": {
3236
"@playwright/test": "^1.44.1",
33-
"@rocketseat/eslint-config": "^1.2.0"
37+
"@rocketseat/eslint-config": "^1.2.0",
38+
"@types/lodash.debounce": "^4.0.9"
3439
}
3540
}

src/app/artigos/Article.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export interface Article {
2+
id: string
3+
imageUrl: string
4+
title: string
5+
slug: string
6+
excerpt: string
7+
author: string
8+
createdAt: string
9+
}

src/app/artigos/ArticleCard.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import Image from 'next/image'
2+
import { Article } from './Article'
3+
4+
interface ArticleCardProps {
5+
article: Article
6+
}
7+
8+
export function ArticleCard(props: ArticleCardProps) {
9+
return (
10+
<div className="cursor-pointer col-span-1 hover:bg-gray-700 transition-all p-2 rounded-lg hover:scale-105">
11+
<Image
12+
alt={`capa do artigo ${props.article.title}`}
13+
src={props.article.imageUrl}
14+
height={400}
15+
width={500}
16+
className="rounded-md overflow-hidden object-cover h-24 line-clamp-2"
17+
/>
18+
<h2 className="font-bold text-lg mt-2">{props.article.title}</h2>
19+
<p className="line-clamp-3 text-gray-400">{props.article.excerpt}</p>
20+
<p className="text-sm text-gray-400 mt-2">
21+
{props.article.author} | {props.article.createdAt}
22+
</p>
23+
</div>
24+
)
25+
}

src/app/artigos/ArticleList.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Article } from './Article'
2+
import { ArticleCard } from './ArticleCard'
3+
4+
interface ArticleListProps {
5+
articles: Article[]
6+
}
7+
8+
export function ArticleList({ articles }: ArticleListProps) {
9+
return (
10+
<div className="grid grid-cols-3 max-lg:grid-cols-2 max-sm:grid-cols-1 max-sm:mx-8 items-center mx-auto gap-4 max-w-6xl">
11+
{articles.map((article) => (
12+
<ArticleCard key={article.id} article={article} />
13+
))}
14+
</div>
15+
)
16+
}

src/app/artigos/EmptyState.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Folder } from 'lucide-react'
2+
3+
export function EmptyState() {
4+
return (
5+
<div className="grid gap-4 max-w-sm mx-auto mt-12">
6+
<Folder className="h-10 w-10" />
7+
<h2 className="font-bold text-xl">Nenhum resultado encontrado</h2>
8+
<p>
9+
Não encontrados um artigo relacioando a sua busca, tente buscar por
10+
outro termo.
11+
</p>
12+
</div>
13+
)
14+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use client'
2+
3+
import { zodResolver } from '@hookform/resolvers/zod'
4+
import { Search } from 'lucide-react'
5+
import { useForm } from 'react-hook-form'
6+
import { z } from 'zod'
7+
8+
const searchSchema = z.object({
9+
query: z.string(),
10+
})
11+
12+
export type SearchForm = z.infer<typeof searchSchema>
13+
14+
interface SeachInputFieldProps {
15+
onSubmit(search: SearchForm): void
16+
onChange(search: SearchForm): void
17+
}
18+
19+
export function SeachInputField(props: SeachInputFieldProps) {
20+
const { register, handleSubmit, reset } = useForm<SearchForm>({
21+
resolver: zodResolver(searchSchema),
22+
})
23+
24+
function submitButtonActionHandler(search: SearchForm) {
25+
props.onSubmit(search)
26+
reset()
27+
}
28+
29+
return (
30+
<form
31+
onSubmit={handleSubmit(submitButtonActionHandler)}
32+
className="flex gap-2 max-w-lg mx-auto transition-all"
33+
>
34+
<div className="p-2 flex gap-2 border-gray-200 border-2 rounded-lg">
35+
<input
36+
{...register('query')}
37+
type="text"
38+
placeholder="Busque conteudo"
39+
className="bg-transparent outline-none"
40+
/>
41+
</div>
42+
<button
43+
type="submit"
44+
className="transition-colors p-2 mx-auto flex gap-2 border-gray-200 text-gray-200 border-2 rounded-lg max-w-md hover:border-gray-100 hover:text-gray-100"
45+
>
46+
<Search />
47+
</button>
48+
</form>
49+
)
50+
}

0 commit comments

Comments
 (0)