Skip to content
This repository has been archived by the owner on Sep 26, 2024. It is now read-only.

fix: searching broke the page and make it blank #524

Merged
merged 3 commits into from
Apr 14, 2024
Merged
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
151 changes: 15 additions & 136 deletions src/components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,139 +1,18 @@
import { MutableRefObject, useRef, useState } from "react";
import { useDebounce, useDidUpdate, useKeys } from "rooks";

import { fetchRecommendations } from "../lib/supabase";
import searchNormal from "../assets/searchNormal.svg";
import cmdKIcon from "../assets/cmdK.svg";
import SearchedRepoCard from "./SearchedRepoCard";
import { Combobox } from "@headlessui/react";

const Hero = () => {
const containerRef = useRef<Document>(document);
const searchBoxRef = useRef<HTMLInputElement>(null);
const comboButtonRef = useRef<HTMLButtonElement>(null);
const [searchTerm, setSearchTerm] = useState("");
const setValueDebounced = useDebounce(setSearchTerm, 500);
const [fetchedData, setFetchedData] = useState<DbRepo[]>([]);
const [comboBoxSelection, setComboBoxSelection] = useState("");
const [hasFocus, setFocus] = useState(false);

const handleCmdK = async (e: KeyboardEvent) => {
comboButtonRef.current?.click();
if (!hasFocus) {
searchBoxRef.current?.focus();
setFocus(true);
const results = await fetchRecommendations(3, searchTerm);

setFetchedData(results);
} else {
searchBoxRef.current?.blur();
setFocus(false);
}

// prevent browser from handling CMD/CTRL + K
e.preventDefault();
};

const useKey = (superKey: string, key: string, target: MutableRefObject<Document>) => {
useKeys([superKey, key], handleCmdK, { target });
};

useKey("ControlLeft", "KeyK", containerRef);

useKey("ControlRight", "KeyK", containerRef);

useKey("MetaRight", "KeyK", containerRef);

useKey("MetaLeft", "KeyK", containerRef);

useDidUpdate(async () => {
const results = await fetchRecommendations(3, searchTerm);

setFetchedData(results);
}, [searchTerm]);

return (
<div className="flex flex-col py-24 items-center mx-2.5">
<div>
<h1 className="font-Lexend text-4xl md:text-5xl text-center text-lightSlate leading-tight tracking-tight">
{`Find `}

<span className="bg-gradient-to-r from-gradFirst via-gradMiddle to-gradLast bg-clip-text text-transparent">
Open-Source Repositories
</span>

<br />
to contribute today
</h1>
</div>

<Combobox
as="div"
value={comboBoxSelection}
onChange={setComboBoxSelection}
>
<div className="mt-11 px-4 py-2.5 bg-white shadow-2xl rounded-2xl md:min-w-[26.375rem] flex justify-between">
<div className="flex items-center gap-x-2.5">
<img
alt="search icon"
src={searchNormal}
/>

<Combobox.Button ref={comboButtonRef}>
<Combobox.Input
ref={searchBoxRef}
className="w-full outline-none text-base text-lightSlate"
displayValue={() => searchTerm}
placeholder="Search repositories"
type="text"
value={searchTerm}
onChange={e => setValueDebounced(e.target.value)}
onFocus={() => setFocus(true)}
onBlur={() =>
setTimeout(() => {
setFocus(false);
}, 200)}
onKeyUp={(event: React.KeyboardEvent) => {
if (event.key === "Enter") {
window.open(comboBoxSelection, "_blank", "noreferrer");
}
}}
/>
</Combobox.Button>
</div>

<img
alt="command k"
className="pt-1.5"
src={cmdKIcon}
/>
</div>

<div className="mt-2.5">
<Combobox.Options className="flex w-full justify-center">
{fetchedData.length > 0 && (
<div className="flex md:min-w-96 pb-2 absolute z-50 max-w-96 flex-col bg-white rounded-2.5 shadow-2xl">
<div className="bg-gray-100 py-2.5 px-10 md:px-3.5 border-b-gray-100 border-b-0.5 rounded-2.5 rounded-b-none w-full">
<p className="text-gray-500 text-sm font-semibold">Repository</p>
</div>

{fetchedData.map(data => (
<Combobox.Option
key={data.full_name}
as="a"
className={({ active }) => (active ? "bg-gray-50" : "")}
value={`https://app.opensauced.pizza/s/${data.full_name}`}
>
<SearchedRepoCard data={data} />
</Combobox.Option>
))}
</div>
)}
</Combobox.Options>
</div>
</Combobox>
const Hero = () => (
<div className="flex flex-col py-24 items-center mx-2.5">
<div>
<h1 className="font-Lexend text-4xl md:text-5xl text-center text-lightSlate leading-tight tracking-tight">
{`Find `}

<span className="bg-gradient-to-r from-gradFirst via-gradMiddle to-gradLast bg-clip-text text-transparent">
Open-Source Repositories
</span>

<br />
to contribute today
</h1>
</div>
);
};
</div>
);

export default Hero;
50 changes: 37 additions & 13 deletions src/components/HotRepoCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const HotRepoCard = ({ repoName }: HotRepoCardProps): JSX.Element => {
rel="noreferrer"
target="_blank"
href={`${String(
`${bugReportLink} repo not found [${repoName}]&body=Please take a look why this ${repoName} not founded`
`${bugReportLink} repo not found [${repoName}]&body=Please take a look why this ${repoName} not founded`,
)}`}
>
Report a bug
Expand All @@ -40,7 +40,10 @@ const HotRepoCard = ({ repoName }: HotRepoCardProps): JSX.Element => {
if (isLoading) {
return (
<div className="p-4 border rounded-2xl bg-white w-full space-y-1 relative">
<Skeleton enableAnimation count={5} />
<Skeleton
enableAnimation
count={5}
/>
</div>
);
}
Expand All @@ -52,9 +55,15 @@ const HotRepoCard = ({ repoName }: HotRepoCardProps): JSX.Element => {
<div className="p-4 border rounded-2xl bg-white w-full space-y-1 relative">
<div className="flex justify-between w-full">
<div className="flex space-x-1 items-center">
<img alt="Hot Repo Icon" className="h-4 w-4 rounded-md overflow-hidden" src={getAvatarLink(owner)} />

<span className="text-sm font-medium text-lightSlate11">{owner}</span>
<img
alt="Hot Repo Icon"
className="h-4 w-4 rounded-md overflow-hidden"
src={getAvatarLink(owner)}
/>

<span className="text-sm font-medium text-lightSlate11">
{owner}
</span>
</div>
</div>

Expand All @@ -68,25 +77,40 @@ const HotRepoCard = ({ repoName }: HotRepoCardProps): JSX.Element => {
{name}
</a>

<p className="text-gray-500 font-medium text-xs w-5/6">{description}</p>
<p className="text-gray-500 font-medium text-xs w-5/6">
{description}
</p>
</div>

<div className="flex items-center justify-between absolute bottom-3 inset-x-0 px-4">
<div className="flex space-x-3 text-xs">
<div className="flex text-sm space-x-1 justify-center items-center">
<VscIssues className="fill-lightSlate10" size={16} />

<span className="text-lightSlate11">{humanizeNumber(issues)}</span>
<VscIssues
className="fill-lightSlate10"
size={16}
/>

<span className="text-lightSlate11">
{humanizeNumber(issues)}
</span>
</div>

<div className="flex text-sm space-x-1 justify-center items-center">
<AiOutlineStar className="fill-lightSlate10" size={16} />

<span className="text-lightSlate11">{humanizeNumber(stars)}</span>
<AiOutlineStar
className="fill-lightSlate10"
size={16}
/>

<span className="text-lightSlate11">
{humanizeNumber(stars)}
</span>
</div>

<div className="flex text-sm space-x-1 justify-center items-center">
<BiGitPullRequest className="fill-lightSlate10" size={16} />
<BiGitPullRequest
className="fill-lightSlate10"
size={16}
/>

<span className="text-lightSlate11">0</span>
</div>
Expand Down
37 changes: 21 additions & 16 deletions src/components/PrimaryNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@ const PrimaryNav = (): JSX.Element => {
useEffect(() => {
const fetchAuthSession = async () => {
if (currentUser?.access_token) {
await fetch(`${import.meta.env.VITE_API_URL}/auth/session`, {
headers: { accept: "application/json", Authorization: `Bearer ${currentUser.access_token}` },
}).catch((err) => console.log("error: ", err));
await fetch(`${import.meta.env.VITE_API_URL}/auth/session`, { headers: { accept: "application/json", Authorization: `Bearer ${currentUser.access_token}` } }).catch(err => console.log("error: ", err));
}
};

fetchAuthSession().catch((err) => console.log(err));
fetchAuthSession().catch(err => console.log(err));
}, [userAndTokens]);

return (
Expand All @@ -42,14 +40,21 @@ const PrimaryNav = (): JSX.Element => {
<div className="flex font-OpenSans py-6 px-10 justify-between max-w-screen-2xl mx-auto">
<div className="flex items-center text-osGrey">
<a href="/">
<img alt="Open Sauced Logo" className="inline-block w-6 h-6 mr-1" src={openSaucedLogo} />
<img
alt="Open Sauced Logo"
className="inline-block w-6 h-6 mr-1"
src={openSaucedLogo}
/>

<span className="text-lg leading-snug font-black tracking-tighter">OpenSauced</span>
</a>
</div>

{userAndTokens && (
<Menu as="div" className="flex z-50 text-left relative">
<Menu
as="div"
className="flex z-50 text-left relative"
>
<div className="flex items-center">
<StarTheRepo userAndTokens={userAndTokens} />

Expand Down Expand Up @@ -90,18 +95,21 @@ const PrimaryNav = (): JSX.Element => {
</div>

<div className="flex-col shrink">
<p className="text-osGrey text-xs font-semibold">{userAndTokens.user.user_metadata.full_name}</p>
<p className="text-osGrey text-xs font-semibold">
{userAndTokens.user.user_metadata.full_name}
</p>

<p className="text-gray-500 text-xs font-normal">{userAndTokens.user.user_metadata.user_name}</p>
<p className="text-gray-500 text-xs font-normal">
{userAndTokens.user.user_metadata.user_name}
</p>
</div>
</div>
</Menu.Item>

<Menu.Item>
{({ active }) => (
<button
className={`${
active ? "bg-gray-100 text-gray-700" : "text-gray-900"
className={`${active ? "bg-gray-100 text-gray-700" : "text-gray-900"
} group flex w-full items-center rounded-md px-5 py-1.5 text-sm`}
>
{`v${version}`}
Expand All @@ -112,8 +120,7 @@ const PrimaryNav = (): JSX.Element => {
<Menu.Item>
{({ active }) => (
<button
className={`${
active ? "bg-gray-100 text-gray-700" : "text-gray-900"
className={`${active ? "bg-gray-100 text-gray-700" : "text-gray-900"
} group flex w-full items-center rounded-md px-5 py-1.5 text-sm`}
onClick={async () => {
if (!currentUser?.access_token) {
Expand All @@ -134,8 +141,7 @@ const PrimaryNav = (): JSX.Element => {
href={bugReportLink}
rel="noreferrer"
target="_blank"
className={`${
active ? "bg-gray-100 text-gray-700" : "text-gray-900"
className={`${active ? "bg-gray-100 text-gray-700" : "text-gray-900"
} group flex w-full items-center rounded-md px-5 py-1.5 text-sm`}
>
Report a bug
Expand All @@ -146,8 +152,7 @@ const PrimaryNav = (): JSX.Element => {
<Menu.Item>
{({ active }) => (
<button
className={`${
active ? "bg-gray-100 text-gray-700" : "text-gray-900"
className={`${active ? "bg-gray-100 text-gray-700" : "text-gray-900"
} group flex w-full items-center rounded-md px-5 py-1.5 text-sm`}
onClick={async () => signOut()}
>
Expand Down
44 changes: 0 additions & 44 deletions src/lib/supabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,47 +48,3 @@ export async function updateVotesByRepo (votes: number, repo_id: number, user_id

return votes + modifier;
}

export async function fetchRecommendations (
limit = 25,
textToSearchParam = "",
) {
const orderBy = "stars";
const orderByOptions: {
ascending?: boolean,
nullsFirst?: boolean,
foreignTable?: string
} | undefined = { ascending: false };
const selectStatement = `
id,
user_id,
full_name,
name,
description,
stars,
issues,
starsRelation:users_to_repos_stars(starsCount:count),
`;

const supabaseComposition = supabase
.from("repos")
.select(selectStatement)
.filter("starsRelation.deleted_at", "is", null);

const searchColumn = textToSearchParam === "" ? "" : "full_name";
const textToSearch = textToSearchParam === "" ? "" : textToSearchParam;

const { data: recommendations, error } = await supabaseComposition
.limit(limit)
.like(searchColumn, `%${textToSearch}%`)
.order("last_merged_at", {
ascending: false,
foreignTable: "contributions",
})
.order(orderBy, orderByOptions)
.order("updated_at", { ascending: false });

error && console.error(error);

return recommendations as DbRepo[];
}
Loading