Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create lazy loading corrected #110

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 62 additions & 62 deletions src/components/Activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,74 +7,74 @@ import { useEffect, useState } from "react";
import { client } from "@/config/appwrite-client";

export default function Activity() {
const [activity, setActivity] = useState([]);
const [activity, setActivity] = useState([]);

const getActivity = async () => {
const res = await fetch("/api/activity");
const data = await res.json();
setActivity(data);
};
const getActivity = async () => {
const res = await fetch("/api/activity");
const data = await res.json();
setActivity(data);
};

useEffect(() => {
const events = [
`databases.${process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID}.collections.${process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_RATINGS_ID}.documents`,
];
client.subscribe(events, () => getActivity());
getActivity();
}, []);
useEffect(() => {
const events = [
`databases.${process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID}.collections.${process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_RATINGS_ID}.documents`,
];
client.subscribe(events, () => getActivity());
getActivity();
}, []);

return (
<>
<header className="flex items-center justify-between border-b border-white/5 px-4 py-4 sm:px-6 sm:py-6 lg:px-8">
<h2 className="text-base font-semibold leading-7 text-white">
Activity feed
</h2>
{/* <a
return (
<>
<header className="flex items-center justify-between border-b border-white/5 px-4 py-4 sm:px-6 sm:py-6 lg:px-8">
<h2 className="text-base font-semibold leading-7 text-white">
Activity feed
</h2>
{/* <a
href="#"
className="text-sm font-semibold leading-6 text-indigo-400"
>
View all
</a> */}
</header>
<ul role="list" className="divide-y divide-white/5">
{activity.map((rating, idx) => (
<li key={idx} className="px-4 py-4 sm:px-6 lg:px-8">
<div className="flex items-center gap-x-3">
<Link
href={`https://github.com/${rating.username}`}
target="_blank"
>
<Image
className="h-6 w-6 flex-none rounded-full bg-gray-800"
src={`https://github.com/${rating.username}.png`}
alt={`Logo for ${rating.name}`}
width={20}
height={20}
/>
</Link>
<Link
href={`https://github.com/${rating.username}`}
target="_blank"
className="flex-auto truncate text-sm font-semibold leading-6 text-white"
>
{rating.username}
</Link>
<time
dateTime={rating.$updatedAt}
className="flex-none text-xs text-gray-600"
>
{rating.timeAgo}
</time>
</div>
<p className="mt-3 truncate text-sm text-gray-500">
Rated{" "}
<Link className="text-gray-400" href={rating.url} target="_blank">
{rating.url.split("github.com/")[1]}
</Link>
</p>
</li>
))}
</ul>
</>
);
</header>
<ul role="list" className="divide-y divide-white/5">
{activity.map((rating, idx) => (
<li key={idx} className="px-4 py-4 sm:px-6 lg:px-8">
<div className="flex items-center gap-x-3">
<Link
href={`https://github.com/${rating.username}`}
target="_blank"
>
<Image
className="h-6 w-6 flex-none rounded-full bg-gray-800"
src={`https://github.com/${rating.username}.png`}
alt={`Logo for ${rating.name}`}
width={20}
height={20}
/>
</Link>
<Link
href={`https://github.com/${rating.username}`}
target="_blank"
className="flex-auto truncate text-sm font-semibold leading-6 text-white"
>
{rating.username}
</Link>
<time
dateTime={rating.$updatedAt}
className="flex-none text-xs text-gray-600"
>
{rating.timeAgo}
</time>
</div>
<p className="mt-3 truncate text-sm text-gray-500">
Rated{" "}
<Link className="text-gray-400" href={rating.url} target="_blank">
{rating.url.split("github.com/")[1]}
</Link>
</p>
</li>
))}
</ul>
</>
);
}
11 changes: 11 additions & 0 deletions src/components/ListSkeletons/ActivitySkeleton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";

const ActivitySkeleton = () => {
return (
<div className="w-full">
<div className="skeleton w-full h-20 bg-slate-900 rounded-none mt-4 lg:mt-0"></div>
</div>
);
};

export default ActivitySkeleton;
12 changes: 12 additions & 0 deletions src/components/ListSkeletons/RepoListSkeleton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const RepoListSkeleton = () => {
return (
<div className="w-11/12 mx-auto">
<div className="w-full flex items-center my-4">
<div className="skeleton w-20 h-20 bg-slate-900 rounded-none mt-4 lg:mt-0"></div>
<div className="skeleton w-full h-20 bg-slate-900 mx-4 rounded-none mt-4 lg:mt-0"></div>
</div>
</div>
);
};

export default RepoListSkeleton;
12 changes: 12 additions & 0 deletions src/components/ListSkeletons/StatSkeleton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const StatSkeleton = () => {
return (
<div className="w-11/12 grid grid-cols-1 gap-px bg-white/5 sm:grid-cols-2 lg:grid-cols-4">
<div className="skeleton w-48 h-36 bg-slate-900 rounded-none lg:mt-0"></div>
<div className="skeleton w-48 h-36 bg-slate-900 rounded-none lg:mt-0 lg:mx-4"></div>
<div className="skeleton w-48 h-36 bg-slate-900 rounded-none lg:mt-0"></div>
<div className="skeleton w-48 h-36 bg-slate-900 rounded-none lg:mt-0"></div>
</div>
);
};

export default StatSkeleton;
81 changes: 9 additions & 72 deletions src/components/Repos.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
"use client";

import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import { ChevronRightIcon } from "@heroicons/react/20/solid";
import dynamic from "next/dynamic";

import { client } from "@/config/appwrite-client";
import { classNames } from "@/utils/classNames";
import RepoListSkeleton from "./ListSkeletons/RepoListSkeleton";

const RepoList = dynamic(() => import("./componentList/RepoList"), {
loading: RepoListSkeleton,
ssr: false,
});

const statuses = {
research: "text-orange-500 bg-orange-100/10",
recommend: "text-green-400 bg-green-400/10",
caution: "text-rose-400 bg-rose-400/10",
};
const badges = {
research: "text-orange-500 bg-orange-100/10 ring-orange-400/20",
recommend: "text-green-400 bg-green-400/10 ring-green-400/20",
caution: "text-rose-400 bg-rose-400/10 ring-rose-400/20",
};
const groups = {
recommend: 70,
research: 40,
Expand Down Expand Up @@ -47,7 +40,7 @@ export default function Repos({ minimumVotes = 5, keyword, sort }) {
params.push(`sort=${sort}`);
}
const res = await fetch(
`/api/repos${params.length ? `?${params.join("&")}` : ""}`
`/api/repos${params.length ? `?${params.join("&")}` : ""}`,
);

const data = await res.json();
Expand Down Expand Up @@ -75,63 +68,7 @@ export default function Repos({ minimumVotes = 5, keyword, sort }) {
return (
<ul role="list" className="divide-y divide-white/5">
{repos.map((repo, idx) => (
<li
key={idx}
className="relative flex items-center space-x-4 px-4 py-4 sm:px-6 lg:px-8"
>
<Image
className="inline-block rounded-md h-12 w-12"
src={repo.logo}
alt={`Logo for ${repo.owner}/${repo.name}`}
width={40}
height={40}
/>
<div className="min-w-0 flex-auto">
<div className="flex items-center gap-x-3">
<div
className={classNames([
statuses[repo.status],
"flex-none rounded-full p-1",
])}
>
<div className="h-2 w-2 rounded-full bg-current" />
</div>
<h2 className="min-w-0 text-sm font-semibold leading-6 text-white">
<Link
href={`/rate?owner=${repo.owner}&name=${repo.name}`}
className="flex gap-x-2"
>
<span className="truncate">{repo.owner}</span>
<span className="text-gray-400">/</span>
<span className="whitespace-nowrap">{repo.name}</span>
<span className="absolute inset-0" />
</Link>
</h2>
</div>
<div className="mt-3 flex items-center gap-x-2.5 text-xs leading-5 text-gray-400">
<p className="truncate">{repo.description}</p>
<svg
viewBox="0 0 2 2"
className="h-0.5 w-0.5 flex-none fill-gray-300"
>
<circle cx={1} cy={1} r={1} />
</svg>
<p className="whitespace-nowrap">{repo.status}</p>
</div>
</div>
<div
className={classNames([
badges[repo.status],
"rounded-full flex-none py-1 px-2 text-xs font-medium ring-1 ring-inset",
])}
>
{repo.rating.toFixed(1)} / 5 ({repo.votes})
</div>
<ChevronRightIcon
className="h-5 w-5 flex-none text-gray-400"
aria-hidden="true"
/>
</li>
<RepoList key={idx} repo={repo} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RepoList component is used within a map function to render the list of repositories. The key prop is set to the index of the map, which is not recommended in React when the list can change. If the repositories have unique identifiers, it would be better to use those as keys to help React identify which items have changed, are added, or are removed.

- <RepoList key={idx} repo={repo} />
+ <RepoList key={repo.id} repo={repo} />

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
<RepoList key={idx} repo={repo} />
<RepoList key={repo.id} repo={repo} />

))}
</ul>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/SideNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default function SideNav({ setKeyword, children }) {
account.createOAuth2Session(
"github",
`${process.env.NEXT_PUBLIC_BASE_URL}/`,
`${process.env.NEXT_PUBLIC_BASE_URL}/`
`${process.env.NEXT_PUBLIC_BASE_URL}/`,
);
};

Expand Down
98 changes: 49 additions & 49 deletions src/components/Stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,56 @@ import { client } from "@/config/appwrite-client";
import { abbreviateNumber } from "@/utils/abbreviateNumbers";

export default function Stats() {
const [stats, setStats] = useState([]);
const [stats, setStats] = useState([]);

const getStats = async () => {
const res = await fetch("/api/stats");
const data = await res.json();
const stats = [
{ name: "Total Ratings", value: data.ratings, unit: "⭐️" },
{ name: "Total Repos", value: data.repos, unit: "GitHub" },
{ name: "Total Stars", value: data.stars, unit: "⭐️" },
{
name: "Recommended Repos",
value: ((data.stars / data.ratings / 5) * 100).toFixed(1),
unit: "%",
},
];
setStats(stats);
};
const getStats = async () => {
const res = await fetch("/api/stats");
const data = await res.json();
const stats = [
{ name: "Total Ratings", value: data.ratings, unit: "⭐️" },
{ name: "Total Repos", value: data.repos, unit: "GitHub" },
{ name: "Total Stars", value: data.stars, unit: "⭐️" },
{
name: "Recommended Repos",
value: ((data.stars / data.ratings / 5) * 100).toFixed(1),
unit: "%",
},
];
setStats(stats);
};

useEffect(() => {
const events = [
`databases.${process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID}.collections.${process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_APP_ID}.documents`,
];
client.subscribe(events, () => getStats());
getStats();
}, []);
useEffect(() => {
const events = [
`databases.${process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID}.collections.${process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_APP_ID}.documents`,
];
client.subscribe(events, () => getStats());
getStats();
}, []);

return (
<div className="bg-gray-900 flex grow">
<div className="mx-auto max-w-7xl">
<div className="grid grid-cols-1 gap-px bg-white/5 sm:grid-cols-2 lg:grid-cols-4">
{stats.map((stat) => (
<div
key={stat.name}
className="bg-gray-900 px-4 py-6 sm:px-6 lg:px-8"
>
<p className="text-sm font-medium leading-6 text-gray-400">
{stat.name}
</p>
<p className="mt-2 flex items-baseline gap-x-2">
<span className="text-4xl font-semibold tracking-tight text-white">
{abbreviateNumber(stat.value)}
</span>
{stat.unit ? (
<span className="text-sm text-gray-400">{stat.unit}</span>
) : null}
</p>
</div>
))}
</div>
</div>
</div>
);
return (
<div className="bg-gray-900 flex grow">
<div className="mx-auto max-w-7xl">
<div className="grid grid-cols-1 gap-px bg-white/5 sm:grid-cols-2 lg:grid-cols-4">
{stats.map((stat) => (
<div
key={stat.name}
className="bg-gray-900 px-4 py-6 sm:px-6 lg:px-8"
>
<p className="text-sm font-medium leading-6 text-gray-400">
{stat.name}
</p>
<p className="mt-2 flex items-baseline gap-x-2">
<span className="text-4xl font-semibold tracking-tight text-white">
{abbreviateNumber(stat.value)}
</span>
{stat.unit ? (
<span className="text-sm text-gray-400">{stat.unit}</span>
) : null}
</p>
</div>
))}
</div>
</div>
</div>
);
}
Loading