Skip to content

Commit 20ad048

Browse files
committed
1 parent 2fbaeb0 commit 20ad048

File tree

8 files changed

+113
-16
lines changed

8 files changed

+113
-16
lines changed

examples/graphql/src/app/index.scss

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
--clr-foreground--selected: #dfecff;
66
}
77
// normalize
8+
html,
9+
body,
10+
#root,
11+
.app {
12+
height: 100%;
13+
position: relative;
14+
}
15+
816
.app {
917
li {
1018
list-style: none;
@@ -14,14 +22,13 @@
1422
.app {
1523
display: flex;
1624
flex-direction: column;
17-
18-
.page {
25+
&-content {
1926
margin: auto 10%;
20-
&-title {
21-
display: flex;
22-
justify-content: center;
23-
margin: 10px;
24-
}
27+
flex-grow: 1;
28+
}
29+
30+
.ant-breadcrumb {
31+
margin: 20px;
2532
}
2633
}
2734

@@ -30,4 +37,7 @@
3037
.text-white {
3138
color: white;
3239
}
40+
.text-muted {
41+
color: gray;
42+
}
3343
}

examples/graphql/src/app/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const App = () => {
1212
Todo App
1313
</span>
1414
</Layout.Header>
15-
<Layout.Content>
15+
<Layout.Content className="app-content">
1616
<Routing />
1717
</Layout.Content>
1818
</Layout>
Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
import React from 'react'
2+
import { RouteComponentProps } from "react-router-dom";
3+
import {Alert, Spin } from "antd";
4+
import { TaskCard } from "shared/components";
5+
import { useFetch } from "shared/hooks";
26

3-
const TaskDetails = () => {
4-
return (
5-
<div>
6-
page:TaskDetails
7-
</div>
8-
)
7+
type Props = RouteComponentProps<{
8+
id: string;
9+
}>;
10+
11+
const TaskDetails = (props: Props) => {
12+
const { id } = props.match.params;
13+
const { data, loading, error } = useFetch<Task>(`todos/${id}`);
14+
console.log({ error });
15+
if (loading) return <Spin />;
16+
if (error) return <Alert message={error.message || String(error)} type="error" showIcon />;
17+
if (data === null) return <>Not Found</>;
18+
return <TaskCard {...data} />;
919
}
1020

1121
export default TaskDetails
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { default as TaskItem } from "./task-item";
2+
export { default as TaskCard } from "./task-card";
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.task-card {
2+
min-height: 80%;
3+
height: inherit;
4+
5+
& > .ant-card-body {
6+
display: flex;
7+
}
8+
9+
&__details {
10+
flex-grow: 1;
11+
height: 100%;
12+
}
13+
14+
&__sidebar {
15+
border-left: 1px solid lightgray;
16+
padding-left: 20px;
17+
height: 100%;
18+
}
19+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React from 'react';
2+
import cn from "classnames";
3+
import { Card, Steps, Typography, Divider } from "antd";
4+
import { UserOutlined, HomeOutlined } from "@ant-design/icons";
5+
import { useFetch } from "shared/hooks";
6+
import "./index.scss";
7+
8+
type Props = Task;
9+
10+
const ICON_STYLE = { color: '#08c' };
11+
12+
const getTaskStatus = (completed: boolean) => {
13+
if (completed) return 1;
14+
return 0;
15+
};
16+
17+
// TODO: as feature
18+
const TaskCard = (props: Props) => {
19+
const { completed, id, title, userId } = props;
20+
const { data: author } = useFetch<User>(`users/${userId}`);
21+
22+
return (
23+
<Card
24+
className={cn("task-card", { completed })}
25+
title={`Task - ${title}`}
26+
>
27+
<div className="task-card__details">
28+
<i className="text-muted">Task description</i>
29+
</div>
30+
<div className="task-card__sidebar">
31+
<div className="task-card__author">
32+
<Typography.Title level={5}>Author</Typography.Title>
33+
<span className="task-card__author" >
34+
<UserOutlined style={ICON_STYLE} /> {author?.username} {`<${author?.email}>`}
35+
<br />
36+
<HomeOutlined style={ICON_STYLE} /> {author?.company.name}
37+
</span>
38+
</div>
39+
<Divider />
40+
<div className="task-card__status">
41+
<Typography.Title level={5}>Status</Typography.Title>
42+
<Steps direction="vertical" current={getTaskStatus(completed)}>
43+
<Steps.Step title="Created" description="Task was created and added in todo-list." />
44+
<Steps.Step title="Finished" description="Task was completed by author." />
45+
</Steps>
46+
</div>
47+
</div>
48+
</Card>
49+
)
50+
}
51+
52+
export default TaskCard

examples/graphql/src/shared/components/task-item/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import "./index.scss";
77

88
type Props = Task;
99

10+
// TODO: as feature
1011
const TaskItem = (props: Props) => {
1112
const { completed, title, userId, id } = props;
1213
const { data: author } = useFetch<User>(`users/${userId}`);

examples/graphql/src/shared/hooks/use-fetch.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ import { API_DOMAIN } from "shared/get-env";
44
const useFetch = <T = any>(url: string, baseUrl = API_DOMAIN) => {
55
const [loading, setLoading] = useState<boolean>(false);
66
const [data, setData] = useState<T | null>(null);
7-
const [error, setError] = useState(null);
7+
const [error, setError] = useState<any>(null);
88

99
useEffect(() => {
1010
setLoading(true);
1111
fetch(`${baseUrl}/${url}`)
12-
.then((r) => r.json())
12+
.then((r) => {
13+
console.log(r.status);
14+
if (r.status >= 200 && r.status < 300) return r.json();
15+
throw new Error("Not Found");
16+
})
1317
.then((r: T) => {
1418
setData(r);
1519
setLoading(false);

0 commit comments

Comments
 (0)