Skip to content

Commit 163484e

Browse files
authored
feat: display ideas from db (freeCodeCamp-2025-Summer-Hackathon#75)
1 parent 963a56e commit 163484e

File tree

3 files changed

+66
-47
lines changed

3 files changed

+66
-47
lines changed

backend/src/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class Idea(Model):
4141

4242

4343
class IdeaPublic(BaseModel):
44+
id: ObjectId
4445
name: str
4546
description: str
4647
upvoted_by: list[ObjectId] = []

frontend/src/App.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function App() {
2626
path='/'
2727
element={
2828
<>
29-
<IdeaFormSection />
29+
<IdeaFormSection count='3' />
3030
<IdeaSubmissionForm />
3131
<LandingPageContent />
3232
</>

frontend/src/components/IdeaFormSection.jsx

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,72 @@
1-
import React from 'react';
2-
import './../styles.css';
1+
import { useCallback, useEffect, useState } from 'react';
2+
import { Link } from 'react-router';
3+
4+
const IdeaFormSection = ({ count }) => {
5+
let [isLoading, setLoading] = useState(true);
6+
let [error, setError] = useState(null);
7+
let [data, setData] = useState([]);
8+
9+
const fetchIdeas = useCallback(async () => {
10+
setError(null);
11+
setLoading(true);
12+
try {
13+
const response = await fetch(
14+
import.meta.env.VITE_API_LOCATION + `/ideas/?limit=${count}`
15+
);
16+
17+
if (!response.ok) {
18+
throw new Error(response.statusText);
19+
}
20+
21+
setLoading(false);
22+
setData((await response?.json())?.data);
23+
} catch (e) {
24+
console.error(e);
25+
setError(e);
26+
}
27+
}, [count]);
28+
29+
useEffect(() => {
30+
fetchIdeas();
31+
}, [fetchIdeas]);
332

4-
const IdeaFormSection = () => {
533
return (
634
<section className='idea-form-section'>
735
<div className='voting-section' tabIndex='0'>
836
<h3>Vote on Current Ideas</h3>
9-
<ul className='idea-list'>
10-
<li className='idea-item'>
11-
<span className='idea-text'>Add a dark mode to the interface</span>
12-
<div className='vote-controls'>
13-
<button className='image-only-upvote-button'>
14-
<img
15-
src='https://i.ibb.co/DfxLPp7g/Upvote-transparent-2.png'
16-
alt='Upvote'
17-
className='upvote-icon'
18-
/>
19-
</button>
20-
<span className='vote-count'>120</span>
21-
</div>
22-
</li>
23-
<li className='idea-item'>
24-
<span className='idea-text'>Implement real-time collaboration</span>
25-
<div className='vote-controls'>
26-
<button className='image-only-upvote-button'>
27-
<img
28-
src='https://i.ibb.co/DfxLPp7g/Upvote-transparent-2.png'
29-
alt='Upvote'
30-
className='upvote-icon'
31-
/>
32-
</button>
33-
<span className='vote-count'>95</span>
34-
</div>
35-
</li>
36-
<li className='idea-item'>
37-
<span className='idea-text'>
38-
Integrate with Slack for notifications
39-
</span>
40-
<div className='vote-controls'>
41-
<button className='image-only-upvote-button'>
42-
<img
43-
src='https://i.ibb.co/DfxLPp7g/Upvote-transparent-2.png'
44-
alt='Upvote'
45-
className='upvote-icon'
46-
/>
47-
</button>
48-
<span className='vote-count'>78</span>
49-
</div>
50-
</li>
51-
</ul>
37+
{error ? (
38+
`${error}`
39+
) : isLoading ? (
40+
'Loading...'
41+
) : (
42+
<ul className='idea-list'>
43+
{data.length === 0
44+
? "There's no ideas, add yours!"
45+
: data.map(({ id, name, upvoted_by }) => {
46+
return (
47+
<Link to={`/ideas/${id}`} key={id}>
48+
<li className='idea-item'>
49+
<span className='idea-text'>{name}</span>
50+
<div className='vote-controls'>
51+
<form onSubmit={() => {}}>
52+
<button className='image-only-upvote-button'>
53+
<img
54+
src='https://i.ibb.co/DfxLPp7g/Upvote-transparent-2.png'
55+
alt='Upvote'
56+
className='upvote-icon'
57+
/>
58+
</button>
59+
</form>
60+
<span className='vote-count'>
61+
{upvoted_by?.length}
62+
</span>
63+
</div>
64+
</li>
65+
</Link>
66+
);
67+
})}
68+
</ul>
69+
)}
5270
</div>
5371
</section>
5472
);

0 commit comments

Comments
 (0)