forked from EddieHubCommunity/good-first-issue-finder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path+page.svelte
124 lines (109 loc) · 3.69 KB
/
+page.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<script lang="ts">
import LoadMore from '$lib/components/load-more.svelte';
import Toggle from '$lib/components/toggle.svelte';
import Seo from '$lib/components/seo.svelte';
import { goto, disableScrollHandling, afterNavigate } from '$app/navigation';
import type { PageData } from './$types';
import { query } from '$lib/constants.json';
import Loader from '$lib/components/loader.svelte';
import { createInfiniteQuery } from '@tanstack/svelte-query';
import { fetchIssues } from '$lib/data';
import IssueCard from '$lib/components/issue-card.svelte';
import Filter from '$lib/components/filter.svelte';
import Search from '$lib/components/search.svelte';
import Modal from '$lib/components/modal.svelte';
export let data: PageData;
let { checked } = data;
let searchString = '';
if (!checked) checked = false;
let selectedLabels: string[] = [];
$: issues = createInfiniteQuery({
queryKey: ['issues', { global: checked }],
queryFn: ({ pageParam }) => fetchIssues(checked ? query.global : query.org, pageParam),
getNextPageParam: (lastPage) => {
if (lastPage.pageInfo.hasNextPage) return lastPage.pageInfo.endCursor;
return undefined;
},
});
afterNavigate(() => {
disableScrollHandling();
});
const onChangeHandler = async () => {
if (checked) {
await goto('?global=true', { noScroll: true });
return;
}
await goto('?global=false', { noScroll: true });
};
const onFilterClear = () => {
selectedLabels = [];
};
$: uniqueTags = $issues.data?.pages?.reduce((acc, page) => {
page.labels.forEach((label) => {
if (!acc.includes(label)) {
acc.push(label);
}
});
return acc;
}, [] as string[]);
$: filteredResponse = $issues.data?.pages?.flatMap((page) => {
return page.edges
.filter((edge) => {
const labels = edge.node.labels.edges.map((node) => node.node.name);
return selectedLabels.every((label) => labels.includes(label));
})
.filter((edge) => {
if (searchString === '') {
return true;
}
const title = edge.node.title.toLowerCase();
return title.includes(searchString.trim().toLowerCase());
});
});
// SEO Parameters
const title = 'Dashboard | Good First Issue Finder';
const metadescription =
'Find good first issues by either querying the EddieHub organization or the community';
</script>
<Seo {title} {metadescription} />
<div class="flex flex-col items-center justify-center">
<div class="mb-4">
<div class="justify-self-center">
<Toggle
id="toggle"
bind:checked
labelLeft="EddieHub"
labelRight="GitHub"
on:change={onChangeHandler}
/>
</div>
</div>
<div class="flex justify-center">
<Search bind:searchTerm={searchString} />
<div class="flex items-center justify-center">
<Modal clearFilter={onFilterClear} title="Filters" amount={selectedLabels}>
<Filter bind:group={selectedLabels} tags={uniqueTags || []} />
</Modal>
</div>
</div>
</div>
{#if $issues.isInitialLoading}
<div class="mt-8 flex items-center justify-center gap-4">
<Loader background="off-background" /> Loading...
</div>
{:else if filteredResponse}
{#if filteredResponse.length < 1}
<div class="mt-4 text-center">Unfortunately, there were no issues found.</div>
{:else}
<div class="mb-4 mt-6 space-y-4">
{#each filteredResponse as edge}
<IssueCard issue={edge.node} />
{/each}
</div>
{#if $issues.hasNextPage}
<div class="flex items-center justify-center">
<LoadMore isDisabled={$issues.isFetchingNextPage} on:load={() => $issues.fetchNextPage()} />
</div>
{/if}
{/if}
{/if}