实现基本功能
This commit is contained in:
11
src/components/RepositoryItem.tsx
Normal file
11
src/components/RepositoryItem.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react'
|
||||
|
||||
export interface RepoItemProps {
|
||||
name:string
|
||||
star_count:number|null,
|
||||
fork_count:number|null
|
||||
}
|
||||
|
||||
export default function RepoItem (props:RepoItemProps) {
|
||||
return <li>{props.name} - 🌟{props.star_count} - 🍴{props.fork_count}</li>
|
||||
}
|
99
src/components/RepositoryList.tsx
Normal file
99
src/components/RepositoryList.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { search as SearchRepository } from '../api/repository'
|
||||
import RepopositoryItem from './RepositoryItem'
|
||||
import { RepositorySearchResultItem } from '../api/api'
|
||||
import classes from './style/RepositoryList.module.css'
|
||||
|
||||
interface RepositoryListProps {
|
||||
|
||||
/** 搜索关键词 */
|
||||
keyword:string
|
||||
|
||||
/** 最多允许缓存多少页 */
|
||||
max_cache_page:number
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认每一页多少条记录
|
||||
* https://docs.github.com/en/rest/reference/repos
|
||||
*/
|
||||
const DEFAULT_PER_PAGE = 30
|
||||
|
||||
export default function RepositoryList (props:RepositoryListProps) {
|
||||
/** 当前页 */
|
||||
const [current_page, setCurrentPage] = useState(1)
|
||||
|
||||
/** 总页码 */
|
||||
const [total_page, setTotalPage] = useState(0)
|
||||
|
||||
/** 上一页按钮是否可点击 */
|
||||
const [prev_button_enable, setPrevButtonEnable] = useState(false)
|
||||
|
||||
/** 下一页按钮是否可点击 */
|
||||
const [next_button_enable, setNextButtonEnable] = useState(false)
|
||||
|
||||
/** 接口加载中 */
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const [list, setList] = useState<RepositorySearchResultItem[]>([])
|
||||
|
||||
async function search (page:number) {
|
||||
setLoading(true)
|
||||
try {
|
||||
/* eslint-disable */
|
||||
var result = await SearchRepository(props.keyword, page)
|
||||
} catch (err) {
|
||||
setLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
const _total_page = Math.ceil(result.total_count / DEFAULT_PER_PAGE)
|
||||
setTotalPage(_total_page)
|
||||
|
||||
setCurrentPage(page)
|
||||
|
||||
setList(result.items)
|
||||
|
||||
setPrevButtonEnable(page>1)
|
||||
setNextButtonEnable(page<_total_page)
|
||||
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
search(1)
|
||||
}, [])
|
||||
|
||||
function onClickPrev(){
|
||||
search(current_page-1)
|
||||
}
|
||||
|
||||
function onClickNext(){
|
||||
search(current_page+1)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes['list-wrapper']}>
|
||||
<ul className={classes.list}>
|
||||
{
|
||||
list.map(item => <RepopositoryItem key={item.id} name={item.name} star_count={item.stargazers_count} fork_count={item.forks_count} />)
|
||||
}
|
||||
</ul>
|
||||
{
|
||||
list.length===0 && <span>暂无数据</span>
|
||||
}
|
||||
{
|
||||
loading && <div className={classes.loading}></div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="action-bar">
|
||||
<button disabled={loading || !prev_button_enable} onClick={onClickPrev}>上一页</button>
|
||||
<button disabled={loading || !next_button_enable} onClick={onClickNext}>下一页</button>
|
||||
<span> {current_page} / {total_page}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
34
src/components/style/RepositoryList.module.css
Normal file
34
src/components/style/RepositoryList.module.css
Normal file
@@ -0,0 +1,34 @@
|
||||
.wrapper {
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wrapper .list-wrapper {
|
||||
min-width:360px;
|
||||
min-height:630px;
|
||||
display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-bottom:15px;
|
||||
}
|
||||
|
||||
.wrapper .list-wrapper .loading {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
z-index:10;
|
||||
background-color: rgba(0,0,0,.8);
|
||||
width:100%;
|
||||
height:100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.wrapper .list-wrapper .loading:after{
|
||||
content:'loading...';
|
||||
color:#fff;
|
||||
}
|
Reference in New Issue
Block a user