实现基本功能

This commit is contained in:
2021-07-26 17:26:58 +08:00
commit 78addb6d96
22 changed files with 8717 additions and 0 deletions

View 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>
}

View 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>
)
}

View 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;
}