| [2e0035f] | 1 | import { useEffect, useState } from 'react'
|
|---|
| 2 | import { api } from '../lib/api.js'
|
|---|
| 3 |
|
|---|
| 4 | export default function Feed() {
|
|---|
| 5 | const [posts, setPosts] = useState([])
|
|---|
| 6 | const [openId, setOpenId] = useState(null)
|
|---|
| 7 | const [comments, setComments] = useState([])
|
|---|
| 8 | const [draft, setDraft] = useState('')
|
|---|
| 9 | const [error, setError] = useState(null)
|
|---|
| 10 |
|
|---|
| 11 | const load = () => api.get('/posts/feed').then(setPosts).catch(e => setError(e.message))
|
|---|
| 12 | useEffect(() => { load() }, [])
|
|---|
| 13 |
|
|---|
| 14 | const open = async (id) => {
|
|---|
| 15 | setOpenId(id)
|
|---|
| 16 | setComments(await api.get(`/posts/${id}/comments`))
|
|---|
| 17 | }
|
|---|
| 18 |
|
|---|
| 19 | const send = async () => {
|
|---|
| 20 | if (!draft.trim()) return
|
|---|
| 21 | try {
|
|---|
| 22 | await api.post(`/posts/${openId}/comments`, { description: draft })
|
|---|
| 23 | setDraft('')
|
|---|
| 24 | setComments(await api.get(`/posts/${openId}/comments`))
|
|---|
| 25 | load()
|
|---|
| 26 | } catch (e) { setError(e.message) }
|
|---|
| 27 | }
|
|---|
| 28 |
|
|---|
| 29 | return (
|
|---|
| 30 | <div>
|
|---|
| 31 | {error && <div className="error">{error}</div>}
|
|---|
| 32 | {posts.length === 0 && <p className="muted">Nothing published yet.</p>}
|
|---|
| 33 |
|
|---|
| 34 | {posts.map(p => (
|
|---|
| 35 | <div className="card" key={p.id}>
|
|---|
| 36 | <div className="row">
|
|---|
| 37 | <h3 style={{ flex: 1 }}>{p.recipeName || '(photo post)'}</h3>
|
|---|
| 38 | <span className="kcal">{p.kcalPerServing} kcal / portion</span>
|
|---|
| 39 | </div>
|
|---|
| 40 | <div className="muted">
|
|---|
| 41 | by {p.authorUsername} · {new Date(p.createdAt).toLocaleString()} · {p.commentCount} comments
|
|---|
| 42 | {p.isFavourite && ' · favourite'}
|
|---|
| 43 | </div>
|
|---|
| 44 | <div className="row" style={{ marginTop: 8 }}>
|
|---|
| 45 | <button className="small" onClick={() => open(p.id)}>
|
|---|
| 46 | {openId === p.id ? 'comments below' : 'open comments'}
|
|---|
| 47 | </button>
|
|---|
| 48 | </div>
|
|---|
| 49 |
|
|---|
| 50 | {openId === p.id && (
|
|---|
| 51 | <div style={{ marginTop: 10, borderTop: '1px solid var(--line)', paddingTop: 10 }}>
|
|---|
| 52 | {comments.map(c => (
|
|---|
| 53 | <div key={c.id} style={{ marginBottom: 6 }}>
|
|---|
| 54 | <b>{c.authorUsername}</b> <span className="muted">
|
|---|
| 55 | {new Date(c.createdAt).toLocaleString()}</span>
|
|---|
| 56 | <div>{c.description}</div>
|
|---|
| 57 | </div>
|
|---|
| 58 | ))}
|
|---|
| 59 | <div className="row" style={{ marginTop: 8 }}>
|
|---|
| 60 | <input style={{ flex: 1 }} placeholder="write a comment"
|
|---|
| 61 | value={draft} onChange={e => setDraft(e.target.value)} />
|
|---|
| 62 | <button className="primary" onClick={send}>Send</button>
|
|---|
| 63 | </div>
|
|---|
| 64 | </div>
|
|---|
| 65 | )}
|
|---|
| 66 | </div>
|
|---|
| 67 | ))}
|
|---|
| 68 | </div>
|
|---|
| 69 | )
|
|---|
| 70 | }
|
|---|