Skip to content

Commit

Permalink
feat: Kudos Issues checkbox added #82
Browse files Browse the repository at this point in the history
  • Loading branch information
ipapandinas committed Mar 6, 2024
1 parent 148a86b commit 95e4bea
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 102 deletions.
35 changes: 35 additions & 0 deletions assets/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,38 @@ export const InfoIcon: React.FC<IconSvgProps> = ({
</svg>
);
};

export const KudosCertifiedIcon: React.FC<IconSvgProps> = ({ ...props }) => {
return (
<svg
aria-label="Kudos Certified logo"
fill="none"
height="3120"
viewBox="0 0 3120 3120"
width="3120"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<g clipRule="evenodd" fillRule="evenodd">
<path
d="m965.318 1905.08c68.572 3.46 133.422 18.82 191.862 46.55 59.52 28.24 113.16 66.43 156.76 114.47 43.71 46.64 77.55 101.8 102 161.93 23.53 57.87 38.86 120.35 40.05 186.67 6.39 83.69-11.7 162.7-42.19 235.08-32.65 77.51-85.3 143.13-149.23 197.04l-82.81 57.46-114.91-165.62 82.81-57.46c47.42-26.68 90.44-61.09 119.92-107.2 29.84-46.67 50.3-100.27 54.8-159.3.88-48.86-6.53-96.13-24.49-138.51-18.57-43.84-48.24-81.54-82.44-113.6-34.12-30.97-74.74-54.2-118.79-69.98-41.5-14.86-86.61-20.37-133.342-18-142.898 6.73-274.304-47.77-371.411-138.21-99.199-92.41-158.413-225.32-161.907-371.42 3.341-146.14 62.407-279.27 161.664-371.67 97.158-90.45 228.73-144.75 371.661-137.8 96.335 4.79 186.625-27.18 252.265-87.996 34.35-31.821 63.5-70.061 81.6-114.029 17.44-42.375 23.54-89.613 21.95-138.227-4.16-61.466-25.68-117.255-57.29-165.376-31.27-47.629-76.55-83.316-126.97-109.549l-85.42-53.491 106.99-170.842 85.42 53.491c70.53 52.429 129.08 119.188 166.12 199.136 34.77 75.066 55.23 158.311 49.25 246.631-2.18 66.611-18.36 129.069-42.6 186.976-25.07 59.891-59.39 114.596-102.84 161.496-87.37 94.3-210.06 154.12-348.475 161-91.814 4.46-170.951 48.78-229.056 111.19-55.891 60.04-89.351 140.66-87.335 229.06-2.112 88.45 31.149 169.25 87.085 229.3 58.118 62.41 137.472 106.47 229.299 110.8z"
fill="#ffcd29"
stroke="#ffcd29"
strokeWidth="96"
/>
<g strokeWidth="72">
<path
d="m1428.8 1801.6h-108.8l.01-217.6h108.8c163.2 11.58 310 62.07 418.88 144.17 92.43 69.69 158.08 156.64 187.82 253.1 13.6 44.11 21.88 89.44 19.57 136.39 5.87 87.28 56.79 162.15 131.89 218.95 97.06 73.43 237.75 108.51 390.12 97.11h108.8v217.6h-108.8c-163.15-11.84-309.75-62.56-418.53-144.72-92.26-69.67-157.61-156.52-187.58-252.78-13.71-44.02-22.22-89.26-20.16-136.16-6.07-87.2-57.28-161.69-132.36-218.43-96.99-73.31-237.41-108.79-389.66-97.63z"
fill="#fcfcfc"
stroke="#fcfcfc"
/>
<path
d="m1645.61 1405.85h-92.78v-185.55h92.77c60.72 2.42 116.96-15.39 163.83-46.85 21.64-14.53 42.66-29.42 60.52-48.44 29.37-31.28 57.72-64.01 71.07-106.5 5.67-18.05 9.15-36.855 10.78-56.388-1.4-21.178.16-41.882 1.23-62.432 4.71-91.13 34.06-175.085 89.69-242.355 71.48-86.432 184-133.408 304.78-138.95h92.78v185.555h-92.78c-69.98-3.104-133.81 21.036-184.7 61.459-13.76 10.925-28.02 20.704-40.22 33.402-29.8 31.02-58 64.14-71.16 106.796-5.57 18.061-8.68 36.986-10.11 56.525 1.59 21.197.22 41.918-.74 62.498-4.29 91.29-33.96 175.42-89.73 242.74-71.59 86.42-184.37 133.23-305.23 138.49z"
fill="#ffcd29"
stroke="#ffcd29"
/>
</g>
</g>
</svg>
);
};
25 changes: 7 additions & 18 deletions components/filters/checkbox-filter.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
"use client";
import React from "react";
import React, { ReactNode } from "react";
import { usePathname, useRouter } from "next/navigation";
import { Checkbox } from "@nextui-org/checkbox";
import { Tooltip } from "@nextui-org/tooltip";
import { InfoIcon } from "@/assets/icons";
import { GOOD_FIRST_ISSUE_LABELS } from "@/data/filters";
import { createUrl } from "@/utils/url";
import { FilterOptions } from "@/types/filters";

interface ICheckboxFilterProps {
paramKey: string;
placeholder: string;
content: ReactNode;
icon: ReactNode;
isSelected?: boolean;
filterOptions: FilterOptions;
onSelect: (values: string[]) => void;
}
export const CheckboxFilter = ({
paramKey,
placeholder,
content,
icon,
isSelected,
filterOptions,
onSelect,
Expand All @@ -34,20 +36,7 @@ export const CheckboxFilter = ({
};

return (
<Tooltip
content={
<div className="px-1 py-2">
<div className="text-small font-bold">
Based on the following GitHub labels:
</div>
{GOOD_FIRST_ISSUE_LABELS.map((label, idx) => (
<div className="text-tiny" key={idx}>
{label}
</div>
))}
</div>
}
>
<Tooltip content={content}>
<div className="flex">
<Checkbox
classNames={{
Expand All @@ -58,7 +47,7 @@ export const CheckboxFilter = ({
onValueChange={handleValueChange}
>
{placeholder}
<InfoIcon className="text-default-500" size={16} />
{icon}
</Checkbox>
</div>
</Tooltip>
Expand Down
94 changes: 62 additions & 32 deletions components/filters/toolbar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"use client";
import { useRef } from "react";
import { KudosCertifiedIcon, InfoIcon } from "@/assets/icons";
import { KudosIssueTooltipContent } from "@/components/table/row";
import { container } from "@/components/primitives";
import { useFilters } from "@/contexts/filters";
import {
GOOD_FIRST_ISSUE_KEY,
GOOD_FIRST_ISSUE_LABELS,
INTEREST_KEY,
KUDOS_ISSUE_KEY,
LANGUAGES_KEY,
PROJECTS_KEY,
} from "@/data/filters";
Expand Down Expand Up @@ -44,38 +48,64 @@ const Toolbar = ({ label }: IToolbarProps) => {
>
<div className={`pt-6 flex flex-col gap-4 ${container()}`}>
<div className="flex flex-col gap-4 items-start overflow-hidden lg:flex-row lg:items-center">
<div className="flex flex-nowrap overflow-x-auto overflow-y-hidden gap-4 w-full sm:w-auto xl:overflow-visible">
<SelectFilter
placeholder={LANGUAGES_KEY}
mainEmoji="🌐"
options={languages}
selectKeys={filters.languages.map(({ value }) => value)}
onSelect={handleSelect(LANGUAGES_KEY)}
filterOptions={filterOptions}
/>
<SelectFilter
placeholder={INTEREST_KEY}
mainEmoji="🪄"
options={interests}
selectKeys={filters.interests.map(({ value }) => value)}
onSelect={handleSelect(INTEREST_KEY)}
filterOptions={filterOptions}
/>
<SelectFilter
placeholder={PROJECTS_KEY}
mainEmoji="🖥️"
options={repositories}
selectKeys={filters.projects.map(({ value }) => value)}
onSelect={handleSelect(PROJECTS_KEY)}
filterOptions={filterOptions}
/>
<CheckboxFilter
paramKey={GOOD_FIRST_ISSUE_KEY}
placeholder="Good first issues Only"
isSelected={filters[GOOD_FIRST_ISSUE_KEY]}
onSelect={handleSelect(GOOD_FIRST_ISSUE_KEY)}
filterOptions={filterOptions}
/>
<div className="flex flex-nowrap overflow-x-auto overflow-y-hidden gap-8 w-full sm:w-auto xl:overflow-visible">
<div className="flex gap-4">
<SelectFilter
placeholder={LANGUAGES_KEY}
mainEmoji="🌐"
options={languages}
selectKeys={filters.languages.map(({ value }) => value)}
onSelect={handleSelect(LANGUAGES_KEY)}
filterOptions={filterOptions}
/>
<SelectFilter
placeholder={INTEREST_KEY}
mainEmoji="🪄"
options={interests}
selectKeys={filters.interests.map(({ value }) => value)}
onSelect={handleSelect(INTEREST_KEY)}
filterOptions={filterOptions}
/>
<SelectFilter
placeholder={PROJECTS_KEY}
mainEmoji="🖥️"
options={repositories}
selectKeys={filters.projects.map(({ value }) => value)}
onSelect={handleSelect(PROJECTS_KEY)}
filterOptions={filterOptions}
/>
</div>
<div className="flex gap-8">
<CheckboxFilter
paramKey={GOOD_FIRST_ISSUE_KEY}
placeholder="Good first issues Only"
content={
<div className="px-1 py-2">
<div className="text-small font-bold">
Based on the following GitHub labels
</div>
{GOOD_FIRST_ISSUE_LABELS.map((label, idx) => (
<div className="text-tiny" key={idx}>
{label}
</div>
))}
</div>
}
icon={<InfoIcon className="text-default-500" size={16} />}
isSelected={filters[GOOD_FIRST_ISSUE_KEY]}
onSelect={handleSelect(GOOD_FIRST_ISSUE_KEY)}
filterOptions={filterOptions}
/>
<CheckboxFilter
paramKey={KUDOS_ISSUE_KEY}
placeholder="Kudos Issues Only"
content={<KudosIssueTooltipContent />}
icon={<KudosCertifiedIcon className="w-5 h-5" size={16} />}
isSelected={filters[KUDOS_ISSUE_KEY]}
onSelect={handleSelect(KUDOS_ISSUE_KEY)}
filterOptions={filterOptions}
/>
</div>
</div>

{numberOfFilters > 1 && (
Expand Down
22 changes: 10 additions & 12 deletions components/table/row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,7 @@ export const Content = ({
{title}
</h3>
{isCertified && (
<Tooltip
content={
<div className="px-1 py-2">
<div className="text-small font-bold">
Kudos Certified Issue
</div>
<a className="text-primary-500 underline" href="/#kudos-issue">
Learn more
</a>
</div>
}
>
<Tooltip content={<KudosIssueTooltipContent />}>
<div className="hidden absolute -top-1 -left-6 md:block">
<MyImage
className="flex-shrink-0 max-w-5 max-h-5 lg:mb-4"
Expand Down Expand Up @@ -313,6 +302,15 @@ export const ExternalLink = ({ href, title }: IExternalLinkProps) => {
);
};

export const KudosIssueTooltipContent = () => (
<div className="px-1 py-2">
<div className="text-small font-bold">Kudos Certified Issue</div>
<a className="text-primary-500 underline" href="/#kudos-issue">
Learn more
</a>
</div>
);

const getGoodFirstIssueLabel = (isGoodFirstIssue: boolean) => {
return isGoodFirstIssue
? [
Expand Down
34 changes: 19 additions & 15 deletions components/table/static-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ExternalLink, Content, Time, Project } from "./row";
import dynamic from "next/dynamic";
import { useFilters } from "@/contexts/filters";
import { extractRepositoryUrlFromIssue } from "@/utils/github";
import { KUDOS_ISSUE_KEY } from "@/data/filters";

const KUDOS_HIGHLIGHT_STYLES = `before:absolute before:content-['']
before:bg-[conic-gradient(transparent_270deg,_#BABABC,_transparent)]
Expand Down Expand Up @@ -47,7 +48,7 @@ interface IStaticTableProps {
}

const StaticTable = ({ data }: IStaticTableProps) => {
const { filterOptions } = useFilters();
const { filters, filterOptions } = useFilters();
const isMobile = useMediaQuery({ maxWidth: 639 }); // tailwind lg default: 640px
const isLaptop = useMediaQuery({ minWidth: 1024 }); // tailwind lg default: 1024px

Expand Down Expand Up @@ -177,20 +178,23 @@ const StaticTable = ({ data }: IStaticTableProps) => {
)}
</TableHeader>
<TableBody items={data} emptyContent="No contributions to display.">
{(item) => (
<TableRow
key={item.id}
className={
item.isCertified
? `bg-[#1e3054] hover:bg-[#284070] relative overflow-hidden whitespace-nowrap ${KUDOS_HIGHLIGHT_STYLES}`
: ""
}
>
{(columnKey) => (
<TableCell>{renderCell(item, columnKey)}</TableCell>
)}
</TableRow>
)}
{(item) => {
const isHighlighted = item.isCertified && !filters[KUDOS_ISSUE_KEY];
return (
<TableRow
key={item.id}
className={
isHighlighted
? `bg-[#1e3054] hover:bg-[#284070] relative overflow-hidden whitespace-nowrap ${KUDOS_HIGHLIGHT_STYLES}`
: ""
}
>
{(columnKey) => (
<TableCell>{renderCell(item, columnKey)}</TableCell>
)}
</TableRow>
);
}}
</TableBody>
</NextUITable>
);
Expand Down
3 changes: 3 additions & 0 deletions data/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const INTEREST_KEY = "interests";
export const LANGUAGES_KEY = "languages";
export const PROJECTS_KEY = "projects";
export const GOOD_FIRST_ISSUE_KEY = "good-first-issue";
export const KUDOS_ISSUE_KEY = "certified";

export const GOOD_FIRST_ISSUE_LABELS = [
"good first issue",
Expand All @@ -10,3 +11,5 @@ export const GOOD_FIRST_ISSUE_LABELS = [
"C1-mentor",
"D0-easy",
];

export const KUDOS_ISSUE_LABELS = ["kudos", "kudos-milestone"];
39 changes: 22 additions & 17 deletions hooks/useFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Filters,
} from "@/types/filters";
import { getNewFilterOption, initFilters } from "@/utils/filters";
import { GOOD_FIRST_ISSUE_KEY } from "@/data/filters";
import { GOOD_FIRST_ISSUE_KEY, KUDOS_ISSUE_KEY } from "@/data/filters";

export interface IConfigProps {
initialFilters: Filters;
Expand All @@ -30,24 +30,29 @@ export const useFilters = ({
const [filters, setFilters] = useState(initialFilters);
const [filterOptions, _] = useState(initialFilterOptions);

const updateFilter = useCallback((key: FilterKeys, values: string[]) => {
setFilters((prev) => {
// Handle the boolean value for GOOD_FIRST_ISSUE_KEY
if (key === GOOD_FIRST_ISSUE_KEY) {
return { ...prev, [GOOD_FIRST_ISSUE_KEY]: values.includes("true") };
}

const newOptions: FilterOption[] = [];
values.forEach((value) => {
const newOption = getNewFilterOption(key, value, filterOptions);
if (newOption) {
newOptions.push(newOption);
const updateFilter = useCallback(
(key: FilterKeys, values: string[]) => {
setFilters((prev) => {
// Handle the boolean value for GOOD_FIRST_ISSUE_KEY & KUDOS_ISSUE_KEY
if (key === GOOD_FIRST_ISSUE_KEY) {
return { ...prev, [GOOD_FIRST_ISSUE_KEY]: values.includes("true") };
} else if (key === KUDOS_ISSUE_KEY) {
return { ...prev, [KUDOS_ISSUE_KEY]: values.includes("true") };
}
});

return { ...prev, [key]: newOptions };
});
}, []);
const newOptions: FilterOption[] = [];
values.forEach((value) => {
const newOption = getNewFilterOption(key, value, filterOptions);
if (newOption) {
newOptions.push(newOption);
}
});

return { ...prev, [key]: newOptions };
});
},
[filterOptions],
);

const clearFilter = useCallback(
(key: FilterKeys) => setFilters((prev) => ({ ...prev, [key]: [] })),
Expand Down
Loading

0 comments on commit 95e4bea

Please sign in to comment.