diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76a86ed45a..037989e0c7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,40 @@
> All notable changes to this project will be documented in this file
+## [1.56.0](https://github.com/open-sauced/insights/compare/v1.55.0...v1.56.0) (2023-07-17)
+
+
+### π Bug Fixes
+
+* add hidden form for Netlify forms submission ([#1351](https://github.com/open-sauced/insights/issues/1351)) ([8075012](https://github.com/open-sauced/insights/commit/80750124072a742443a89716f9b2e956f7bdcb25))
+* ensure font color of selected interests pill changed is white ([#1342](https://github.com/open-sauced/insights/issues/1342)) ([b778f11](https://github.com/open-sauced/insights/commit/b778f11484d02b4d159fe3cd22f43de4a5c28196))
+* improve loading performance of individual highlight ([#1349](https://github.com/open-sauced/insights/issues/1349)) ([9e193fe](https://github.com/open-sauced/insights/commit/9e193feae32739894051ec9d3236826cb00a1c88))
+* prevent concurrent user profile update requests ([#1372](https://github.com/open-sauced/insights/issues/1372)) ([b23b9df](https://github.com/open-sauced/insights/commit/b23b9df076596b7d5163ef9f8d7bc7f28ecde92a))
+
+
+### π¨ Styles
+
+* text inputs colors were not consistent in the user settings page ([#1360](https://github.com/open-sauced/insights/issues/1360)) ([edae9c4](https://github.com/open-sauced/insights/commit/edae9c4a26bbc21921422356c623f2a8c0ca0939))
+
+
+### π Features
+
+* add force login component to design system ([#1330](https://github.com/open-sauced/insights/issues/1330)) ([9d68ffc](https://github.com/open-sauced/insights/commit/9d68ffcef1bbd2f17f05492d1b4e9d4ce4263de4))
+* add top contributors panel to feeds page ([#1347](https://github.com/open-sauced/insights/issues/1347)) ([5b58dd5](https://github.com/open-sauced/insights/commit/5b58dd532ff495fa921053ee1bb48eef2544d678))
+* added new topics to the list ([#1357](https://github.com/open-sauced/insights/issues/1357)) ([33f03bb](https://github.com/open-sauced/insights/commit/33f03bb53b82e8bb18e49c7e5ccba80c77ab982d))
+* change position of visibility action component ([#1331](https://github.com/open-sauced/insights/issues/1331)) ([f3f615c](https://github.com/open-sauced/insights/commit/f3f615caf3b8a69943d6b1443ac0b35075501b4b))
+* changed the last commit date icon with a calender ([#1350](https://github.com/open-sauced/insights/issues/1350)) ([2ae9d53](https://github.com/open-sauced/insights/commit/2ae9d5330e9231d108a9a20b458aed5398c7d24c))
+* implement featured highlights list ([#1337](https://github.com/open-sauced/insights/issues/1337)) ([ed32594](https://github.com/open-sauced/insights/commit/ed32594c64dc616e57e7b9fbea299ba4584bdb68))
+* implement newsletter submission functionality ([#1332](https://github.com/open-sauced/insights/issues/1332)) ([d996ac7](https://github.com/open-sauced/insights/commit/d996ac714fa2cf6394416fcb542c278634edc394))
+* upgrade to Next 13.4, Supabase helper libs to 0.7.x ([#1301](https://github.com/open-sauced/insights/issues/1301)) ([26876c2](https://github.com/open-sauced/insights/commit/26876c260546815102ac5584c0579e12b1323361))
+
+## [1.56.0-beta.12](https://github.com/open-sauced/insights/compare/v1.56.0-beta.11...v1.56.0-beta.12) (2023-07-17)
+
+
+### π Features
+
+* add top contributors panel to feeds page ([#1347](https://github.com/open-sauced/insights/issues/1347)) ([5b58dd5](https://github.com/open-sauced/insights/commit/5b58dd532ff495fa921053ee1bb48eef2544d678))
+
## [1.56.0-beta.11](https://github.com/open-sauced/insights/compare/v1.56.0-beta.10...v1.56.0-beta.11) (2023-07-17)
diff --git a/components/atoms/TopContributorCard/top-contributor-card.tsx b/components/atoms/TopContributorCard/top-contributor-card.tsx
new file mode 100644
index 0000000000..d6fded5a88
--- /dev/null
+++ b/components/atoms/TopContributorCard/top-contributor-card.tsx
@@ -0,0 +1,79 @@
+import React, { useEffect, useState } from "react";
+
+import Link from "next/link";
+import { useRouter } from "next/router";
+import { getAvatarByUsername } from "lib/utils/github";
+import useFollowUser from "lib/hooks/useFollowUser";
+import useSupabaseAuth from "lib/hooks/useSupabaseAuth";
+
+import Avatar from "../Avatar/avatar";
+import Button from "../Button/button";
+
+export interface TopContributorCardProps {
+ login: string;
+}
+
+const TopContributorCard = ({ login }: TopContributorCardProps) => {
+ const router = useRouter();
+ const currentPath = router.asPath;
+
+ const { isError: notFollowing, follow, unFollow } = useFollowUser(login);
+ const [host, setHost] = useState("");
+ const { sessionToken, signIn } = useSupabaseAuth();
+
+ const handleFollowContributor = async () => {
+ try {
+ if (notFollowing) {
+ await follow();
+ return;
+ }
+ await unFollow();
+ } catch (error) {
+ console.log(error);
+ }
+ };
+
+ useEffect(() => {
+ if (typeof window !== "undefined") {
+ setHost(window.location.origin as string);
+ }
+ }, []);
+
+ return (
+
+
+
+
+ {sessionToken && !notFollowing ? (
+
+ ) : (
+
+ )}
+
+ );
+};
+
+export default TopContributorCard;
diff --git a/components/atoms/TopUserCard/top-user-card.tsx b/components/atoms/TopUserCard/top-user-card.tsx
deleted file mode 100644
index 548a6a602f..0000000000
--- a/components/atoms/TopUserCard/top-user-card.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from "react";
-import { getAvatarByUsername } from "lib/utils/github";
-import Avatar from "../Avatar/avatar";
-import Button from "../Button/button";
-
-export interface TopUserCardProps {
- clasName?: string;
- following: boolean;
- username: string;
-}
-/**
- *
- * additional props to handle follow button click will be added in future versions
- */
-
-const TopUserCard = ({ username, following }: TopUserCardProps) => {
- return (
-
-
- {following ? (
-
- ) : (
-
- )}
-
- );
-};
-
-export default TopUserCard;
diff --git a/components/molecules/TopContributorsPanel/top-contributors-panel.tsx b/components/molecules/TopContributorsPanel/top-contributors-panel.tsx
new file mode 100644
index 0000000000..bc3e8df227
--- /dev/null
+++ b/components/molecules/TopContributorsPanel/top-contributors-panel.tsx
@@ -0,0 +1,32 @@
+import React from "react";
+import TopContributorCard from "components/atoms/TopContributorCard/top-contributor-card";
+import { useFetchTopContributors } from "lib/hooks/useFetchTopContributors";
+import SkeletonWrapper from "components/atoms/SkeletonLoader/skeleton-wrapper";
+
+interface TopContributorsPanelProps {
+ loggedInUserLogin: string;
+}
+const TopContributorsPanel = ({ loggedInUserLogin }: TopContributorsPanelProps) => {
+ const { data, isLoading } = useFetchTopContributors();
+
+ const topContributorsWithoutLoggedInUser = data ? data.filter((user) => user.login !== loggedInUserLogin) : [];
+ const top3Contributors = topContributorsWithoutLoggedInUser.slice(0, 3).map((user) => user.login);
+
+ return (
+
+
Top Contributors
+
+ {isLoading &&
+ Array.from({ length: 3 }).map((_, i) => (
+
+
+
+ ))}
+ {top3Contributors.map((login, i) => (
+
+ ))}
+
+ );
+};
+
+export default TopContributorsPanel;
diff --git a/components/molecules/TopUsersPanel/top-user-panel.tsx b/components/molecules/TopUsersPanel/top-user-panel.tsx
deleted file mode 100644
index 77d647b813..0000000000
--- a/components/molecules/TopUsersPanel/top-user-panel.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from "react";
-import TopUserCard, { TopUserCardProps } from "components/atoms/TopUserCard/top-user-card";
-
-interface TopUsersPanelProps {
- users: TopUserCardProps[];
-}
-const TopUsersPanel = ({ users }: TopUsersPanelProps) => {
- return (
-
-
Top Users
- {users.map((user, i) => (
-
- ))}
-
- );
-};
-
-export default TopUsersPanel;
diff --git a/lib/hooks/useFetchTopContributors.ts b/lib/hooks/useFetchTopContributors.ts
new file mode 100644
index 0000000000..454d4a2150
--- /dev/null
+++ b/lib/hooks/useFetchTopContributors.ts
@@ -0,0 +1,20 @@
+import useSWR, { Fetcher } from "swr";
+import publicApiFetcher from "lib/utils/public-api-fetcher";
+
+type TopContributorsResponse = { login: string }[];
+
+const useFetchTopContributors = () => {
+ const { data, error, mutate } = useSWR(
+ "users/top",
+ publicApiFetcher as Fetcher
+ );
+
+ return {
+ data: data ?? [],
+ isLoading: !error && !data,
+ isError: !!error,
+ mutate,
+ };
+};
+
+export { useFetchTopContributors };
diff --git a/lib/hooks/useFollowUser.ts b/lib/hooks/useFollowUser.ts
index d5395a951e..af2696dbec 100644
--- a/lib/hooks/useFollowUser.ts
+++ b/lib/hooks/useFollowUser.ts
@@ -1,4 +1,4 @@
-import useSWR, { Fetcher } from "swr";
+import useSWR, { Fetcher, useSWRConfig } from "swr";
import publicApiFetcher from "lib/utils/public-api-fetcher";
import useSupabaseAuth from "./useSupabaseAuth";
@@ -6,7 +6,8 @@ interface FollowUserResponse {
data: DbFollowUser;
}
const useFollowUser = (username: string) => {
- const { sessionToken } = useSupabaseAuth();
+ const { sessionToken, user } = useSupabaseAuth();
+ const { mutate: mutateGlobal } = useSWRConfig(); // adding this to mutate the global user data to update the users card status on follow/unfollow
const { data, error, mutate } = useSWR(
username ? `users/${username}/follow` : null,
@@ -23,6 +24,7 @@ const useFollowUser = (username: string) => {
if (req && req.ok) {
mutate();
+ mutateGlobal(`user/${user?.user_metadata?.username}`);
}
};
@@ -36,6 +38,7 @@ const useFollowUser = (username: string) => {
if (req && req.ok) {
mutate();
+ mutateGlobal(`user/${user?.user_metadata?.username}`);
}
};
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 72cca5edbc..d7d928fcf1 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -1,12 +1,12 @@
{
"name": "@open-sauced/insights",
- "version": "1.56.0-beta.11",
+ "version": "1.56.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@open-sauced/insights",
- "version": "1.56.0-beta.11",
+ "version": "1.56.0",
"hasInstallScript": true,
"license": "Apache 2.0",
"dependencies": {
diff --git a/package.json b/package.json
index 2409fe0eac..a5cd054ff5 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "@open-sauced/insights",
"description": "πThe dashboard for open source discovery.",
"keywords": [],
- "version": "1.56.0-beta.11",
+ "version": "1.56.0",
"author": "Brian Douglas ",
"private": true,
"license": "Apache 2.0",
diff --git a/pages/feed/index.tsx b/pages/feed/index.tsx
index 8b1e0dc2fe..85fe04d9ee 100644
--- a/pages/feed/index.tsx
+++ b/pages/feed/index.tsx
@@ -4,6 +4,7 @@ import Link from "next/link";
import formatDistanceToNowStrict from "date-fns/formatDistanceToNowStrict";
import clsx from "clsx";
+import TopContributorsPanel from "components/molecules/TopContributorsPanel/top-contributors-panel";
import useSupabaseAuth from "lib/hooks/useSupabaseAuth";
import { useFetchAllHighlights } from "lib/hooks/useFetchAllHighlights";
import { useFetchHighlightRepos } from "lib/hooks/useFetchHiglightRepos";
@@ -68,6 +69,7 @@ const Feeds: WithPageLayout = (props: HighlightSSRProps) => {
const { data, mutate, setPage, isLoading, meta } = useFetchAllHighlights(selectedRepo);
const { data: emojis } = useFetchAllEmojis();
+
const { data: loggedInUser, isLoading: loggedInUserLoading } = useFetchUser(user?.user_metadata.user_name as string);
const { followers_count, following_count, highlights_count } = loggedInUser || {};
@@ -121,7 +123,7 @@ const Feeds: WithPageLayout = (props: HighlightSSRProps) => {
twitterCard="summary_large_image"
/>
-
+
{user && (
= (props: HighlightSSRProps) => {
/>
)}
+
{singleHighlight && (