Skip to content

Commit 7be4708

Browse files
authored
Implement tweak dashboard top (#11)
1 parent 5655b28 commit 7be4708

File tree

3 files changed

+72
-65
lines changed

3 files changed

+72
-65
lines changed

src/components/dashboard/DashboardHeader.tsx

Lines changed: 62 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { HiOutlineExternalLink } from "react-icons/hi";
21
import { IoArrowBack } from "react-icons/io5";
32
import { MdOutlineRefresh } from "react-icons/md";
43
import { Link } from "react-router";
@@ -8,63 +7,70 @@ interface DashboardHeaderProps {
87
onRefresh: () => void;
98
}
109

11-
function DashboardHeader({ username, onRefresh }: DashboardHeaderProps) {
10+
interface DashboardLinkProps {
11+
label: string;
12+
href: string;
13+
}
14+
15+
const DASHBOARD_LINKS: DashboardLinkProps[] = [
16+
{
17+
label: "Exercises directory",
18+
href: "https://git-mastery.github.io/exercises-directory",
19+
},
20+
{
21+
label: "Report a bug",
22+
href: "https://github.com/git-mastery/git-mastery/issues",
23+
}
24+
];
25+
26+
function DashboardHeaderExternalLinks({ links }: { links: DashboardLinkProps[] }) {
27+
const linkClassName = "text-blue-600 mb-2 flex flex-row gap-2 items-center text-sm underline";
28+
1229
return (
13-
<header>
14-
<h3 className="text-2xl font-bold mb-4">Git Mastery Progress Dashboard</h3>
15-
<div className="mb-6">
16-
<Link to="/" className="text-gray-500 italic mb-2 flex flex-row gap-2 items-center">
17-
<IoArrowBack className="inline-block" /> Back to search
18-
</Link>
19-
<div className="flex flex-row justify-between items-center mb-4">
20-
<div className="flex flex-row gap-2 items-center">
21-
<h1 className="text-4xl font-bold">@{username}</h1>
22-
<a
23-
target="_blank"
24-
className="hover:cursor-pointer text-gray-500"
25-
href={`https://github.com/${username}`}
26-
rel="noopener noreferrer"
27-
aria-label="View GitHub profile"
28-
>
29-
<HiOutlineExternalLink size={24} />
30-
</a>
31-
</div>
32-
<button
33-
type="button"
34-
className="hover:cursor-pointer"
35-
onClick={onRefresh}
36-
aria-label="Refresh progress data"
37-
>
38-
<MdOutlineRefresh size={24} className="text-gray-500" />
39-
</button>
40-
</div>
41-
<p className="text-gray-700 font-semibold">
42-
Find your progress for the various Git Mastery exercises.
43-
</p>
44-
<p className="text-gray-700">
45-
To view all exercises, visit the{" "}
46-
<a
47-
className="text-blue-800 underline"
48-
href="https://git-mastery.github.io/exercises-directory"
49-
target="_blank"
50-
rel="noopener noreferrer"
51-
>
52-
exercises directory
53-
</a>
54-
.
55-
</p>
56-
<p className="mt-2 italic">
57-
If there is a discrepancy, open a ticket with the Git-Mastery team{" "}
58-
<a
59-
className="text-blue-800 underline"
60-
href="https://github.com/git-mastery/git-mastery"
61-
target="_blank"
62-
rel="noopener noreferrer"
63-
>
64-
here
30+
<div className="flex flex-row justify-center gap-2 items-center">
31+
{links.map((link, index) => (
32+
<span key={link.label} className="flex flex-row gap-2 items-center">
33+
<a href={link.href} target="_blank" rel="noopener noreferrer" className={linkClassName}>
34+
{link.label}
6535
</a>
66-
</p>
67-
</div>
36+
{index < links.length - 1 && <span className="text-gray-400 mb-2">|</span>}
37+
</span>
38+
))}
39+
</div>
40+
)
41+
}
42+
43+
function DashboardHeaderToolbar({ onRefresh }: { onRefresh: () => void }) {
44+
return (
45+
<div className="flex flex-row justify-between items-center mb-8 text-gray-500">
46+
<nav>
47+
<Link to="/" className="flex flex-row gap-2 items-center text-sm">
48+
<IoArrowBack size={20}/>
49+
Back to change user
50+
</Link>
51+
</nav>
52+
<button
53+
type="button"
54+
onClick={onRefresh}
55+
aria-label="Refresh progress data"
56+
className="flex flex-row gap-2 items-center text-sm cursor-pointer"
57+
>
58+
<MdOutlineRefresh size={20}/>
59+
Refresh
60+
</button>
61+
</div>
62+
)
63+
}
64+
65+
function DashboardHeader({ username, onRefresh }: DashboardHeaderProps) {
66+
return (
67+
<header className="mb-6">
68+
<DashboardHeaderToolbar onRefresh={onRefresh}/>
69+
<h1 className="text-3xl font-bold mb-4 text-center">Git Mastery Progress Dashboard for <a href={`https://github.com/${username}`} target="_blank" rel="noopener noreferrer" className="text-blue-600 gap-2 items-center hover:underline">
70+
@{username}
71+
</a>
72+
</h1>
73+
<DashboardHeaderExternalLinks links={DASHBOARD_LINKS} />
6874
</header>
6975
);
7076
}

src/components/dashboard/ExerciseTable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ function ExerciseTable({ exercises, progress }: ExerciseTableProps) {
5151
<table className="table-fixed w-full bg-white border border-gray-300 rounded-sm">
5252
<thead>
5353
<tr>
54-
<th className="bg-gray-200 border border-gray-300 px-4 py-2 text-left">
54+
<th className="bg-emerald-700 text-white border border-emerald-800 px-4 py-2 text-left">
5555
Exercise
5656
</th>
57-
<th className="bg-gray-200 border border-gray-300 px-4 py-2 text-left w-40">
57+
<th className="bg-emerald-700 text-white border border-emerald-800 px-4 py-2 text-left w-40">
5858
Status
5959
</th>
6060
</tr>

src/pages/dashboard/(username)/index.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { EXERCISES_DIRECTORY_URL, ExerciseStatus } from "@/constants";
1010
import Spinner from "@/components/ui/Spinner";
1111
import { useCallback, useMemo } from "react";
1212
import { useParams } from "react-router";
13+
import { useQueryClient } from "react-query";
1314

1415
type UserProblemSetStatus = string;
1516

@@ -21,8 +22,7 @@ function DashboardPage() {
2122
const {
2223
data: userProgress,
2324
isLoading: isUserProgressLoading,
24-
isRefetchError: isUserProgressRefetching,
25-
refetch: refetchUserProgress,
25+
isFetching: isUserProgressFetching,
2626
} = useGetUserProgressQuery(user?.login);
2727

2828
const parsedUserProgress = useMemo(() => {
@@ -49,22 +49,23 @@ function DashboardPage() {
4949

5050
const { data: exercises, isLoading: isProblemSetsLoading } = useGetExercisesQuery();
5151

52+
const queryClient = useQueryClient();
5253
const refreshUserProgress = useCallback(async () => {
53-
await refetchUserProgress();
54-
}, [refetchUserProgress]);
54+
await queryClient.invalidateQueries(["get-user-progress", user?.login]);
55+
}, [queryClient, user?.login]);
5556

5657
const isLoading = useMemo(() => {
5758
return (
5859
isUserLoading ||
5960
isUserProgressLoading ||
60-
isUserProgressRefetching ||
61+
isUserProgressFetching ||
6162
isProblemSetsLoading
6263
);
6364
}, [
6465
isUserLoading,
6566
isUserProgressLoading,
66-
isUserProgressRefetching,
67-
isProblemSetsLoading,
67+
isUserProgressFetching,
68+
isProblemSetsLoading
6869
]);
6970

7071
// Dynamically render content based on data availability

0 commit comments

Comments
 (0)