51 lines
1.6 KiB
React
51 lines
1.6 KiB
React
import { useEffect, useState } from 'react'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import { List } from 'antd-mobile'
|
|
import { api } from '../../api/client.js'
|
|
|
|
// 经济文章: 列表, 点进 /macro/articles/:slug
|
|
// 使用 antd-mobile List 仿原生设置/通讯录样式
|
|
export default function ArticlesView() {
|
|
const [articles, setArticles] = useState([])
|
|
const [err, setErr] = useState('')
|
|
const [loading, setLoading] = useState(true)
|
|
const navigate = useNavigate()
|
|
|
|
useEffect(() => {
|
|
let cancelled = false
|
|
setLoading(true)
|
|
api('/articles')
|
|
.then((data) => { if (!cancelled) setArticles(data.articles || []) })
|
|
.catch((e) => !cancelled && setErr(e.message))
|
|
.finally(() => !cancelled && setLoading(false))
|
|
return () => { cancelled = true }
|
|
}, [])
|
|
|
|
if (loading) return <div className="loading">加载中...</div>
|
|
if (err) return <div className="error-banner">{err}</div>
|
|
if (!articles.length) return <div className="empty">暂无文章</div>
|
|
|
|
return (
|
|
<div>
|
|
<div className="page-title">经济文章</div>
|
|
<List className="articles-list" mode="card">
|
|
{articles.map((a) => (
|
|
<List.Item
|
|
key={a.id}
|
|
title={a.title}
|
|
description={
|
|
<>
|
|
<div className="list-item-meta">{a.date}</div>
|
|
<div className="list-item-excerpt">{a.excerpt}</div>
|
|
</>
|
|
}
|
|
arrowIcon
|
|
clickable
|
|
onClick={() => navigate('/macro/articles/' + encodeURIComponent(a.slug))}
|
|
/>
|
|
))}
|
|
</List>
|
|
</div>
|
|
)
|
|
}
|