diff --git a/src/components/Activity.js b/src/components/Activity.js
index 86956db..0b44b3a 100644
--- a/src/components/Activity.js
+++ b/src/components/Activity.js
@@ -7,74 +7,79 @@ 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 (
- <>
-
+
+ >
+ );
}
diff --git a/src/components/ListSkeletons/RepoListSkeleton.js b/src/components/ListSkeletons/RepoListSkeleton.js
new file mode 100644
index 0000000..738e98b
--- /dev/null
+++ b/src/components/ListSkeletons/RepoListSkeleton.js
@@ -0,0 +1,12 @@
+const RepoListSkeleton = () => {
+ return (
+
+ );
+};
+
+export default RepoListSkeleton;
diff --git a/src/components/Repos.js b/src/components/Repos.js
index c099540..5630474 100644
--- a/src/components/Repos.js
+++ b/src/components/Repos.js
@@ -1,138 +1,75 @@
"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,
+ recommend: 70,
+ research: 40,
};
const calStatus = (percentage) => {
- if (percentage >= groups.recommend) {
- return "recommend";
- }
- if (percentage >= groups.research && percentage < groups.recommend) {
- return "research";
- }
- return "caution";
+ if (percentage >= groups.recommend) {
+ return "recommend";
+ }
+ if (percentage >= groups.research && percentage < groups.recommend) {
+ return "research";
+ }
+ return "caution";
};
export default function Repos({ minimumVotes = 5, keyword, sort }) {
- const [repos, setRepos] = useState([]);
- const getRepos = async () => {
- const params = [];
- if (minimumVotes) {
- params.push(`minimumVotes=${minimumVotes}`);
- }
- if (keyword) {
- params.push(`keyword=${keyword}`);
- }
- if (sort) {
- params.push(`sort=${sort}`);
- }
- const res = await fetch(
- `/api/repos${params.length ? `?${params.join("&")}` : ""}`
- );
+ const [repos, setRepos] = useState([]);
+ const getRepos = async () => {
+ const params = [];
+ if (minimumVotes) {
+ params.push(`minimumVotes=${minimumVotes}`);
+ }
+ if (keyword) {
+ params.push(`keyword=${keyword}`);
+ }
+ if (sort) {
+ params.push(`sort=${sort}`);
+ }
+ const res = await fetch(
+ `/api/repos${params.length ? `?${params.join("&")}` : ""}`
+ );
- const data = await res.json();
+ const data = await res.json();
- const repos = data.map((repo) => {
- const percentage = Math.round((repo.rating / 5) * 100);
- return {
- ...repo,
- percentage,
- status: calStatus(percentage),
- };
- });
+ const repos = data.map((repo) => {
+ const percentage = Math.round((repo.rating / 5) * 100);
+ return {
+ ...repo,
+ percentage,
+ status: calStatus(percentage),
+ };
+ });
- setRepos(repos);
- };
+ setRepos(repos);
+ };
- useEffect(() => {
- const events = [
- `databases.${process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID}.collections.${process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_REPOS_ID}.documents`,
- ];
- client.subscribe(events, () => getRepos());
- getRepos();
- }, [keyword, sort]);
+ useEffect(() => {
+ const events = [
+ `databases.${process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID}.collections.${process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_REPOS_ID}.documents`,
+ ];
+ client.subscribe(events, () => getRepos());
+ getRepos();
+ }, [keyword, sort]);
- return (
-
- );
+ return (
+
+ {repos.map((repo, idx) => (
+
+ ))}
+
+ );
}
diff --git a/src/components/SideNav.js b/src/components/SideNav.js
index 1f161f0..8b2c7b3 100644
--- a/src/components/SideNav.js
+++ b/src/components/SideNav.js
@@ -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}/`,
);
};
diff --git a/src/components/Stats.js b/src/components/Stats.js
index 00050ed..361febc 100644
--- a/src/components/Stats.js
+++ b/src/components/Stats.js
@@ -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 (
-
-
-
- {stats.map((stat) => (
-
-
- {stat.name}
-
-
-
- {abbreviateNumber(stat.value)}
-
- {stat.unit ? (
- {stat.unit}
- ) : null}
-
-
- ))}
-
-
-
- );
+ return (
+
+
+
+ {stats.map((stat) => (
+
+
+ {stat.name}
+
+
+
+ {abbreviateNumber(stat.value)}
+
+ {stat.unit ? (
+ {stat.unit}
+ ) : null}
+
+
+ ))}
+
+
+
+ );
}
diff --git a/src/components/Users.js b/src/components/Users.js
index 3ebb89e..f4675d1 100644
--- a/src/components/Users.js
+++ b/src/components/Users.js
@@ -23,7 +23,7 @@ export default async function Users() {
const ratings = await new Databases(clientAdmin()).listDocuments(
process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID,
process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_RATINGS_ID,
- [Query.limit(1000)]
+ [Query.limit(1000)],
);
const users = ratings.documents.reduce((acc, rating) => {
if (!acc[rating.username]) {
diff --git a/src/components/componentList/RepoList.js b/src/components/componentList/RepoList.js
new file mode 100644
index 0000000..d38c9d8
--- /dev/null
+++ b/src/components/componentList/RepoList.js
@@ -0,0 +1,79 @@
+import Image from "next/image";
+import Link from "next/link";
+import React from "react";
+import { ChevronRightIcon } from "@heroicons/react/20/solid";
+import { classNames } from "@/utils/classNames";
+
+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 RepoList = ({ repo }) => {
+ return (
+ <>
+
+
+
+
+
+
+
+ {repo.owner}
+ /
+ {repo.name}
+
+
+
+
+
+
{repo.description}
+
+
{repo.status}
+
+
+
+ {repo.rating.toFixed(1)} / 5 ({repo.votes})
+
+
+
+ >
+ );
+};
+
+export default RepoList;
diff --git a/tailwind.config.js b/tailwind.config.js
index f195917..1bfc2d4 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,18 +1,18 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
- content: [
- "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
- "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
- "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
- ],
- theme: {
- extend: {
- backgroundImage: {
- "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
- "gradient-conic":
- "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
- },
- },
- },
- plugins: [require("daisyui"), require("@tailwindcss/forms")],
+ content: [
+ "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
+ "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
+ "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
+ ],
+ theme: {
+ extend: {
+ backgroundImage: {
+ "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
+ "gradient-conic":
+ "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
+ },
+ },
+ },
+ plugins: [require("daisyui"), require("@tailwindcss/forms")],
};