Skip to content

Commit aafa675

Browse files
authored
Merge pull request #16 from GitDataAI/feature/explore
Feature/explore
2 parents 2001250 + b4d174d commit aafa675

File tree

12 files changed

+864
-26
lines changed

12 files changed

+864
-26
lines changed

public/default.webp

10.7 KB
Binary file not shown.

src/app/(default)/explore/page.tsx

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
'use client'
2+
3+
import { useEffect, useState } from "react";
4+
import { notifications } from "@mantine/notifications";
5+
import {
6+
ExploreItemOrganization,
7+
ExploreItemProduct,
8+
ExploreItemUser
9+
} from "@/component/explore/ExploreItem";
10+
import { ExploreItemHeader } from "@/component/explore/ExploreItemHeader";
11+
import {Pagination} from "@mantine/core";
12+
13+
export type ExplorePageProps =
14+
undefined
15+
| ExploreProduct
16+
| ExploreUser
17+
| ExploreOrganization;
18+
19+
export interface ExploreProduct {
20+
total: number,
21+
type: string,
22+
data: {
23+
created_at: string,
24+
default_branch: string,
25+
description?: string,
26+
fork: number,
27+
star: number,
28+
watch: number,
29+
name: string,
30+
rtype: string,
31+
topic: string[],
32+
uid: string,
33+
updated_at: string,
34+
owner: {
35+
avatar: string,
36+
description?: string,
37+
uid: string,
38+
name: string,
39+
}
40+
}[]
41+
}
42+
43+
export interface ExploreUser {
44+
total: number,
45+
type: string,
46+
data: {
47+
created_at: string,
48+
description?: string,
49+
name: string,
50+
uid: string,
51+
avatar?: string,
52+
updated_at: string,
53+
}[]
54+
}
55+
56+
export interface ExploreOrganization {
57+
total: number,
58+
type: string,
59+
data: {
60+
created_at: string,
61+
description?: string,
62+
name: string,
63+
avatar?: string,
64+
uid: string,
65+
updated_at: string,
66+
repo: number,
67+
member: number,
68+
}[]
69+
}
70+
71+
export default function ExplorePage() {
72+
const [Data, setData] = useState<ExplorePageProps>();
73+
const [Rtype,setRtype] = useState<undefined | "product" | "user" | "organization">();
74+
const [Filter, setFilter] = useState<undefined | 'public' | 'private'>();
75+
const [Search, setSearch] = useState<string>("");
76+
const [Page, setPage] = useState<{
77+
page: number,
78+
size: number,
79+
}>({
80+
page: 1,
81+
size: 10,
82+
})
83+
84+
const FetchData = async () => {
85+
const payload = {
86+
type: Rtype,
87+
filter: Filter,
88+
search: Search,
89+
}
90+
const parma = new URLSearchParams();
91+
parma.append("rtype", payload.type ? payload.type : "product");
92+
parma.append("filter", payload.filter ? payload.filter : "all");
93+
parma.append("search", payload.search);
94+
parma.append("page", Page.page.toString())
95+
parma.append("size", Page.size.toString())
96+
const response = await fetch(`/api/v1/explore?${parma}`, {
97+
method: "GET",
98+
headers: {
99+
"Content-Type": "application/json",
100+
},
101+
});
102+
103+
if (response.status === 200) {
104+
response.json().then((result: ExplorePageProps) => {
105+
if(result) {
106+
setData(result);
107+
}
108+
});
109+
} else {
110+
notifications.show({
111+
title: 'Failed',
112+
message: 'Unable to fetch explore data',
113+
color: 'red',
114+
});
115+
}
116+
};
117+
118+
useEffect(() => {
119+
FetchData().then().catch().finally();
120+
},
121+
// !!!forbid insert FetchData in useEffect deps
122+
[Rtype, Filter, Search,Page.page, Page.size]);
123+
return (
124+
<div className="explore">
125+
<ExploreItemHeader setRtype={(x)=>{
126+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
127+
// @ts-expect-error
128+
setRtype(x)
129+
}} rtype={Rtype} Filter={Filter} setFilter={(x)=>{
130+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
131+
// @ts-expect-error
132+
setFilter(x)
133+
}} search={Search} setSearch={(x)=>{
134+
setSearch(x)
135+
}}
136+
/>
137+
<div className="explore-list">
138+
{
139+
Data?.type === "product" &&
140+
Data?.data?.map((item, index) => (
141+
<ExploreItemProduct props={item as {
142+
created_at: string,
143+
default_branch: string,
144+
description?: string,
145+
fork: number,
146+
star: number,
147+
watch: number,
148+
name: string,
149+
rtype: string,
150+
topic: string[],
151+
uid: string,
152+
updated_at: string,
153+
owner: {
154+
avatar: string,
155+
description?: string,
156+
uid: string,
157+
name: string,
158+
}
159+
}} key={index}/>
160+
))
161+
}
162+
{
163+
Data?.type === "user" &&
164+
Data?.data?.map((item, index) => (
165+
<ExploreItemUser props={item as {
166+
created_at: string,
167+
description?: string,
168+
name: string,
169+
uid: string,
170+
avatar?: string,
171+
updated_at: string,
172+
}} key={index}/>
173+
))
174+
}
175+
{
176+
Data?.type === "organization" &&
177+
Data?.data?.map((item, index) => (
178+
<ExploreItemOrganization props={item as {
179+
created_at: string,
180+
description?: string,
181+
name: string,
182+
avatar?: string,
183+
uid: string,
184+
updated_at: string,
185+
repo: number,
186+
member: number,
187+
}} key={index}/>
188+
))
189+
}
190+
</div>
191+
<Pagination className="explore-pagin" total={Data?.total ? Math.ceil(Data?.total / Page.size) : 1} color={"gray"} onChange={(x)=>{
192+
setPage({
193+
page: x,
194+
size: Page.size,
195+
})
196+
}}/>
197+
</div>
198+
);
199+
}
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
export default function Page(){
2-
return(
3-
<>
4-
</>
5-
)
6-
}
1+
import React from 'react';
2+
// import RepoSetHeader from '@/component/repo/RepoSetHeader';
3+
4+
5+
export default function Repo() {
6+
return (
7+
<div className="repo">
8+
{/*<RepoSetHeader owner={props.owner} repo={props.repo} setting={props.setting} />*/}
9+
<div>
10+
</div>
11+
</div>
12+
);
13+
}

src/component/explore/ExploreItem.tsx

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import React from 'react';
2+
import {CiLink, CiStar} from "react-icons/ci";
3+
import {GoRepo, GoRepoForked} from 'react-icons/go';
4+
import {LuUsers} from "react-icons/lu";
5+
import {useRouter} from "next/navigation";
6+
7+
8+
export interface ExploreItemProductProps {
9+
props:{
10+
created_at: string,
11+
default_branch: string,
12+
description?: string,
13+
fork: number,
14+
star: number,
15+
watch: number,
16+
name: string,
17+
rtype: string,
18+
topic: string[],
19+
uid: string,
20+
updated_at: string,
21+
owner: {
22+
avatar: string,
23+
description?: string,
24+
uid: string,
25+
name: string,
26+
}
27+
}
28+
}
29+
30+
31+
export const ExploreItemProduct = ({props}:ExploreItemProductProps) => {
32+
const Router = useRouter();
33+
return(
34+
<div className="explore-product" onClick={()=>{
35+
Router.replace(`${props.owner.name}/${props.name}`)
36+
}}>
37+
<img className='explore-product-avatar' src={props.owner.avatar ?? '/default.webp'} alt={props.owner.name}/>
38+
<div className="explore-product-title">
39+
<div className="explore-product-title-name">
40+
{props.name}
41+
</div>
42+
<div className="explore-product-title-desc">
43+
{props.description}
44+
</div>
45+
</div>
46+
<div className="explore-product-data">
47+
<div className="explore-product-data-item">
48+
<CiStar />{props.star}
49+
</div>
50+
<div className="explore-product-data-item">
51+
<CiLink />{props.watch}
52+
</div>
53+
<div className="explore-product-data-item">
54+
<GoRepoForked />{props.fork}
55+
</div>
56+
</div>
57+
</div>
58+
)
59+
}
60+
61+
export interface ExploreItemUserProps {
62+
props:{
63+
created_at: string,
64+
description?: string,
65+
name: string,
66+
uid: string,
67+
avatar?: string,
68+
updated_at: string,
69+
}
70+
}
71+
72+
export const ExploreItemUser = ({props}:ExploreItemUserProps) => {
73+
const Router = useRouter();
74+
return(
75+
<div className="explore-users" onClick={() => {
76+
Router.replace(`/${props.name}`)
77+
}}>
78+
<img className='explore-users-avatar' src={props.avatar ?? '/default.webp'} alt={props.name}/>
79+
<div className="explore-users-title">
80+
<div className="explore-users-title-name">
81+
{props.name}
82+
</div>
83+
<div className="explore-users-title-desc">
84+
{props.description}
85+
</div>
86+
</div>
87+
</div>
88+
)
89+
}
90+
export interface ExploreItemOrganizationProps {
91+
props:{
92+
created_at: string,
93+
description?: string,
94+
name: string,
95+
avatar?: string,
96+
uid: string,
97+
updated_at: string,
98+
repo: number,
99+
member: number,
100+
}
101+
}
102+
103+
export const ExploreItemOrganization = ({props}:ExploreItemOrganizationProps) => {
104+
const Router = useRouter();
105+
return(
106+
<div className="explore-organization" onClick={() => {
107+
Router.replace(`/${props.name}`)
108+
}}>
109+
<img className='explore-organization-avatar' src={props.avatar ?? '/default.webp'} alt={props.name}/>
110+
<div className="explore-organization-title">
111+
<div className="explore-organization-title-name">
112+
{props.name}
113+
</div>
114+
<div className="explore-organization-title-desc">
115+
{props.description}
116+
</div>
117+
</div>
118+
<div className="explore-organization-data">
119+
<div className="explore-organization-data-item">
120+
<GoRepo />{props.repo}
121+
</div>
122+
<div className="explore-organization-data-item">
123+
<LuUsers />{props.member}
124+
</div>
125+
</div>
126+
127+
</div>
128+
)
129+
}

0 commit comments

Comments
 (0)