From 476034b7dc47e1f41ba1303da4a10316d61560ef Mon Sep 17 00:00:00 2001
From: tendohassan <113972200+tendohassan@users.noreply.github.com>
Date: Thu, 20 Nov 2025 00:31:28 +0300
Subject: [PATCH] Update index.html
feat: enhance GoodFirstIssue.com with multiple improvements
- Added pagination for better navigation
- Improved mobile responsiveness
- Added token setup instructions and validation
- Enhanced error handling and user feedback
- Added sorting by recently updated
- Better code organization and documentation
---
index.html | 1497 +++++++++++++++++++++++++++++-----------------------
1 file changed, 826 insertions(+), 671 deletions(-)
diff --git a/index.html b/index.html
index 1f6f9d4a..47a71955 100644
--- a/index.html
+++ b/index.html
@@ -1,683 +1,838 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- .com
-
-
-
-
-
-
Find Great Open Source Opportunities.
-
Made for new contributors to find great Open Source projects.
-
Discover Issues and Repositories with and labels.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- | Repository |
- Good First Issues |
- Stars |
- Last Update |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ });
+
+ return fetch('https://api.github.com/graphql', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ 'Authorization': `Bearer ${GITHUB_TOKEN}`,
+ },
+ body: body
+ })
+ .then(response => {
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ return response.json();
+ })
+ .then(data => {
+ if (data.errors) {
+ throw new Error(data.errors[0].message);
+ }
+ return data;
+ });
+ }
+
+ // Main Function
+ function onSubmitButton() {
+ const parameters = getHTMLParameters();
+ if (!parameters.language) {
+ showError('Please select a programming language');
+ return;
+ }
+
+ hideError();
+ showLoadingSpinner();
+ hideEmptyState();
+
+ currentLanguage = parameters.language;
+ currentPage = 1;
+ currentSort = parameters.sortBy;
+
+ const time = new Date().getTime();
+ const todaysDate = new Date();
+ let issuesFetched = [];
+ let labelIndex = 0;
+
+ function makeQuery(endCursor) {
+ const query = makeIssuesQuery(parameters.language, ISSUE_LABELS[labelIndex], endCursor);
+ return fetchQuery(searchIssuesQuery, query);
+ }
+
+ function handleData(data, fetchCount) {
+ if (!data || !data.data) {
+ fetchNextLabel();
+ return;
+ }
+
+ const issues = data.data.search.edges.map(edge => edge.node);
+ issuesFetched = issuesFetched.concat(issues);
+ const pageInfo = data.data.search.pageInfo;
+
+ // Filter out undefined issues
+ for (let i = issues.length - 1; i >= 0; i--) {
+ if (isUndefined(issues[i])) {
+ issues.splice(i, 1);
+ }
+ }
+
+ if (issues.length === 0) {
+ fetchNextLabel();
+ } else if (pageInfo.hasNextPage &&
+ !afterDateLimit(new Date(issues[issues.length - 1].createdAt), todaysDate, 4)) {
+ fetchNextPage(fetchCount + 1, pageInfo);
+ } else {
+ fetchNextLabel();
+ }
+ }
+
+ function fetchNextPage(fetchCount, pageInfo) {
+ makeQuery(pageInfo.endCursor)
+ .then(data => handleData(data, fetchCount))
+ .catch(error => {
+ console.error('Error fetching next page:', error);
+ showError('Failed to load more data. Please try again.');
+ hideLoadingSpinner();
+ });
+ }
+
+ function fetchNextLabel() {
+ labelIndex += 1;
+ if (labelIndex >= ISSUE_LABELS.length) {
+ finishedFetchingRepos();
+ } else {
+ makeQuery()
+ .then(data => handleData(data, 0))
+ .catch(error => {
+ console.error('Error fetching label:', error);
+ showError('Failed to load data. Please try again.');
+ hideLoadingSpinner();
+ });
+ }
+ }
+
+ function finishedFetchingRepos() {
+ hideLoadingSpinner();
+
+ if (issuesFetched.length === 0) {
+ showEmptyState();
+ return;
+ }
+
+ const repoNameDict = {};
+ const repoDict = {};
+ currentRepositories = createContainers(issuesFetched, repoDict, repoNameDict);
+ currentRepositories = sortRepositories(currentRepositories, currentSort);
+
+ renderTable(currentRepositories, currentPage, parameters.resultsPerPage);
+ renderPagination(currentRepositories.length, currentPage, parameters.resultsPerPage);
+
+ // Set up sorting handlers
+ document.querySelectorAll('.sortsTable').forEach(element => {
+ element.addEventListener('click', function() {
+ const sortValue = this.getAttribute('data-sort');
+ currentSort = sortValue;
+ document.getElementById('sortSelect').value = sortValue;
+ currentRepositories = sortRepositories(currentRepositories, sortValue);
+ renderTable(currentRepositories, currentPage, parameters.resultsPerPage);
+ });
+ });
+ }
+
+ // Start the fetching process
+ makeQuery()
+ .then(data => handleData(data, 0))
+ .catch(error => {
+ console.error('Error in main fetch:', error);
+ showError('Failed to load data. Please check your internet connection and try again.');
+ hideLoadingSpinner();
+ });
+ }
+
+ function onSortChange() {
+ const parameters = getHTMLParameters();
+ currentSort = parameters.sortBy;
+
+ if (currentRepositories.length > 0) {
+ currentRepositories = sortRepositories(currentRepositories, currentSort);
+ renderTable(currentRepositories, currentPage, parameters.resultsPerPage);
+ }
+ }
+
+ // Initialize the page
+ document.addEventListener('DOMContentLoaded', function() {
+ // Set up initial state
+ showEmptyState();
+
+ // Add event listeners for sorting table headers
+ document.querySelectorAll('.sortsTable').forEach(element => {
+ element.addEventListener('click', function() {
+ const sortValue = this.getAttribute('data-sort');
+ document.getElementById('sortSelect').value = sortValue;
+ onSortChange();
+ });
+ });
+ });
+
+