Skip to content

Commit d3c83b3

Browse files
authored
Merge pull request #100 from midudev/copilot/fix-47
Add screen to list read and unread questions
2 parents 5b0737a + 7636175 commit d3c83b3

File tree

4 files changed

+93
-11
lines changed

4 files changed

+93
-11
lines changed

app/components/Header.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,11 @@ export function Header({ stars }) {
6565
<div className='absolute right-0 flex items-center gap-x-2 top-1'>
6666
<ThemeToggle />
6767
<Stars stars={stars} />
68-
<button className='border uppercase mix rounded-[4px] font-bold inline-block p-2 text-[10px]'>
69-
Leidas {read}/{counter.total}
70-
</button>
68+
<Link href="/questions">
69+
<button className='border uppercase mix rounded-[4px] font-bold inline-block p-2 text-[10px]'>
70+
Leidas {read}/{counter.total}
71+
</button>
72+
</Link>
7173
</div>
7274
)}
7375

app/components/ListOfQuestions.jsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
import { readIndex } from '../../utils/posts.js'
2-
32
import Link from 'next/link'
3+
import { ReadStatusItem } from './ReadStatusItem.jsx'
44

55
const getListOfQuestions = async () => {
66
const questions = await readIndex()
77
return questions
88
}
99

10-
export async function ListOfQuestions() {
10+
export async function ListOfQuestions({ showReadStatus = false }) {
1111
const questions = await getListOfQuestions()
1212

1313
return (
1414
<ul className='space-y-3'>
1515
{questions.map(({ id, text }) => (
1616
<li key={id}>
17-
<Link
18-
className='leading-snug hover:underline'
19-
href={`/${id}/#content`}
20-
>
21-
{text}
22-
</Link>
17+
{showReadStatus ? (
18+
<ReadStatusItem id={id} text={text} />
19+
) : (
20+
<Link
21+
className='leading-snug hover:underline'
22+
href={`/${id}/#content`}
23+
>
24+
{text}
25+
</Link>
26+
)}
2327
</li>
2428
))}
2529
</ul>

app/components/ReadStatusItem.jsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use client'
2+
3+
import { useState, useEffect, useCallback } from 'react'
4+
import Link from 'next/link'
5+
import { useEventListener } from '../../hooks/useEventListener'
6+
7+
export function ReadStatusItem({ id, text }) {
8+
const [isRead, setIsRead] = useState(false)
9+
10+
useEffect(() => {
11+
const readStorage = JSON.parse(window.localStorage.getItem('read')) || []
12+
setIsRead(readStorage.includes(text))
13+
}, [text])
14+
15+
const handlerStorageListener = useCallback(
16+
event => {
17+
if (event.key === 'read') {
18+
setIsRead(JSON.parse(event.newValue).includes(text))
19+
}
20+
},
21+
[text]
22+
)
23+
24+
useEventListener({
25+
eventName: 'storage',
26+
handler: handlerStorageListener,
27+
})
28+
29+
const itemClassName = isRead
30+
? 'leading-snug hover:underline text-green-600 dark:text-green-400 flex items-center'
31+
: 'leading-snug hover:underline flex items-center'
32+
33+
return (
34+
<Link className={itemClassName} href={`/${id}/#content`}>
35+
{isRead ? (
36+
<span className="inline-block w-3 h-3 mr-2 bg-green-500 rounded-full" title="Pregunta leída"></span>
37+
) : (
38+
<span className="inline-block w-3 h-3 mr-2 bg-gray-300 dark:bg-gray-600 rounded-full" title="Pregunta no leída"></span>
39+
)}
40+
{text}
41+
</Link>
42+
)
43+
}

app/questions/page.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type { Metadata } from 'next'
2+
import { ListOfQuestions } from '../components/ListOfQuestions.jsx'
3+
4+
export const metadata: Metadata = {
5+
title: 'Lista de preguntas para leer - React.js Wiki',
6+
description: 'Lista de todas las preguntas disponibles sobre React.js con indicación de leídas y no leídas',
7+
}
8+
9+
export default function QuestionsPage() {
10+
return (
11+
<>
12+
<h1 className='pb-6 text-3xl font-bold text-blue-900 dark:text-blue-100'>
13+
Lista de preguntas
14+
</h1>
15+
<p className='pb-6 text-lg dark:text-blue-200'>
16+
A continuación encontrarás todas las preguntas disponibles.
17+
</p>
18+
19+
<div className="flex mb-8 gap-4 text-sm">
20+
<div className="flex items-center">
21+
<span className="inline-block w-3 h-3 mr-2 bg-green-500 rounded-full"></span>
22+
<span>Preguntas leídas</span>
23+
</div>
24+
<div className="flex items-center">
25+
<span className="inline-block w-3 h-3 mr-2 bg-gray-300 dark:bg-gray-600 rounded-full"></span>
26+
<span>Preguntas por leer</span>
27+
</div>
28+
</div>
29+
30+
<ListOfQuestions showReadStatus={true} />
31+
</>
32+
)
33+
}

0 commit comments

Comments
 (0)