Skip to content
Open
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
91 changes: 67 additions & 24 deletions components/RepositoryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { Repository } from "../types";
import { LanguageFilter } from "./LanguageFilter";
import { RepositoryItem } from "./RepositoryItem";
import { SDGFilter } from "./SDGFilter";
import {Grid, Stack} from '@primer/react-brand';

import { Grid, Stack } from "@primer/react-brand";

type RepositoryListProps = {
repositories: Repository[];
Expand All @@ -29,36 +28,57 @@ export const RepositoryList = ({ repositories, filter }: RepositoryListProps) =>
const [selectedLanguages, setSelectedLanguages] = useState<string[]>([]);
const [selectedTopics, setSelectedTopics] = useState<string[]>([]);


const filteredRepositories = repositories.filter((repository) => {
const languageFilter =
selectedLanguages.length === 0 || selectedLanguages.includes(repository.language.display);
selectedLanguages.length === 0 ||
selectedLanguages.includes(repository.language.display);

const topicFilter =
selectedTopics.length === 0 ||
repository.topics?.some((topic) => selectedTopics.includes(topic.display));
repository.topics?.some((topic) =>
selectedTopics.includes(topic.display)
);

const nameFilter = Object.values(repository).some(
(value) => value && value.toString().toLowerCase().includes(filter.toLowerCase())
(value) =>
value &&
value.toString().toLowerCase().includes(filter.toLowerCase())
);

const happyContainer = Object.values(repository).some(
(value) => value && value.toString().toLowerCase().includes(filter.toLowerCase())
(value) =>
value &&
value.toString().toLowerCase().includes(filter.toLowerCase())
);

return languageFilter && nameFilter && topicFilter && happyContainer;
});

// ✅ Repository count logic
const totalCount = repositories.length;
const visibleCount = filteredRepositories.length;

const uniqueLanguages = [
...new Set(repositories.map((repository) => repository.language.display))
...new Set(repositories.map((repository) => repository.language.display)),
];
const languageOptions = uniqueLanguages.map((language) => ({ value: language, label: language }));
const languageOptions = uniqueLanguages.map((language) => ({
value: language,
label: language,
}));

const uniqueTopics = [
...new Set(
repositories.flatMap((repository) => repository.topics?.map((topic) => topic.display) ?? [])
)
repositories.flatMap(
(repository) =>
repository.topics?.map((topic) => topic.display) ?? []
)
),
].sort((a, b) => parseInt(a.slice(4)) - parseInt(b.slice(4)));
const topicOptions = uniqueTopics.map((topic) => ({ value: topic, label: IndexedTopics[topic] }));

const topicOptions = uniqueTopics.map((topic) => ({
value: topic,
label: IndexedTopics[topic],
}));

const loadMoreItems = () => setItems(items + itemsPerScroll);
const hasMoreItems = items < filteredRepositories.length;
Expand All @@ -67,26 +87,49 @@ export const RepositoryList = ({ repositories, filter }: RepositoryListProps) =>
<main className="repoWrap">
<div className="grid-wrap">
<Grid>
<Grid.Column span={{xsmall: 12, small: 12, medium: 12, large: 5, xlarge: 3}}>
{/* LEFT COLUMN – FILTERS */}
<Grid.Column
span={{ xsmall: 12, small: 12, medium: 12, large: 5, xlarge: 3 }}
>
<Stack className="stack">
<LanguageFilter
setSelectedLanguages={setSelectedLanguages}
languageOptions={languageOptions}
/>
<SDGFilter setSelectedTopics={setSelectedTopics} topicOptions={topicOptions} />
<SDGFilter
setSelectedTopics={setSelectedTopics}
topicOptions={topicOptions}
/>
</Stack>
</Grid.Column>
<Grid.Column className="repo-list-wrap" span={{xsmall: 12, small: 12, medium: 12, large: 7, xlarge: 9}}>
<InfiniteScroll
dataLength={items}
next={loadMoreItems}
hasMore={hasMoreItems}
loader={<Loader />}
>
{filteredRepositories.slice(0, items).map((repository) => (
<RepositoryItem key={repository.id} repository={repository} />

{/* RIGHT COLUMN – REPOSITORY LIST */}
<Grid.Column
className="repo-list-wrap"
span={{ xsmall: 12, small: 12, medium: 12, large: 7, xlarge: 9 }}
>
{/* ✅ STEP 5: Repository count indicator */}
<p className="text-sm text-gray-500 mb-3">
{visibleCount === totalCount
? `Showing ${totalCount} repositories`
: `Showing ${visibleCount} of ${totalCount} repositories`}
</p>

<InfiniteScroll
dataLength={items}
next={loadMoreItems}
hasMore={hasMoreItems}
loader={<Loader />}
>
{filteredRepositories
.slice(0, items)
.map((repository) => (
<RepositoryItem
key={repository.id}
repository={repository}
/>
))}
</InfiniteScroll>
</InfiniteScroll>
</Grid.Column>
</Grid>
</div>
Expand Down