├── .babelrc ├── .eslintrc.json ├── .gitignore ├── .prettierrc ├── Dockerfile ├── README.md ├── dev.sh ├── package-lock.json ├── package.json ├── public ├── favicon.png ├── index.html ├── manifest.json └── meta-logo.png ├── src ├── components │ ├── App.jsx │ ├── App.scss │ ├── core │ │ ├── Chip.jsx │ │ ├── Chip.scss │ │ ├── Header.jsx │ │ ├── Header.scss │ │ ├── Pagination.jsx │ │ └── Pagination.scss │ ├── scrollToTopButton │ │ ├── ScrollToTopButton.jsx │ │ └── ScrollToTopButton.scss │ ├── search │ │ ├── SearchContainer.jsx │ │ ├── SearchContainer.scss │ │ ├── SearchResult.jsx │ │ ├── SearchResult.scss │ │ ├── SearchResultsContainer.jsx │ │ └── SearchResultsContainer.scss │ ├── statuses │ │ ├── InitialGreeting.jsx │ │ ├── InitialGreeting.scss │ │ ├── LoadingSpinner.jsx │ │ ├── LoadingSpinner.scss │ │ └── NoResultsMessage.jsx │ └── toggles │ │ ├── Labels.jsx │ │ ├── Languages.jsx │ │ ├── ToggleGroup.jsx │ │ ├── TogglesContainer.jsx │ │ └── TogglesContainer.scss ├── images │ ├── github-icon-white.svg │ ├── github-icon.svg │ └── greeting-icon.png ├── index.jsx ├── styles │ ├── _normalize.scss │ ├── _variables.scss │ └── react-toggle.scss └── utils │ ├── color.js │ ├── constants.js │ ├── formatting.js │ └── localStorage.js └── translations ├── README-Czech.md ├── README-French.md ├── README-German.md ├── README-Hindi.md ├── README-Hungarian.md ├── README-Indonesian.md ├── README-Italian.md ├── README-Japanese ├── README-Kannada.md ├── README-Malay.md ├── README-Polish.md ├── README-Portuguese.md ├── README-Romanian.md ├── README-Russian.md ├── README-Spanish.md └── README-Vietnamese.md /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-proposal-class-properties"] 3 | } -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb", "prettier", "prettier/react"], 3 | "parser": "babel-eslint", 4 | "plugins": ["prettier"], 5 | "globals": { 6 | "fetch": false 7 | }, 8 | "env": { 9 | "browser": true 10 | }, 11 | "rules": { 12 | "prettier/prettier": 1, 13 | "eol-last": 0, 14 | "import/prefer-default-export": 0, 15 | "no-trailing-spaces": 0, 16 | "max-len": 0, 17 | "no-unused-vars": 1, 18 | "no-multiple-empty-lines": 0, 19 | "padded-blocks": 1, 20 | "func-names": 0, 21 | "no-console": 0, 22 | "import/order": 0, 23 | "react/sort-comp": 0, 24 | "jsx-a11y/label-has-associated-control": 0, 25 | "jsx-a11y/label-has-for": 0, 26 | "react/prop-types": 0, 27 | "prefer-const": 1, 28 | "react/no-unused-state": 1, 29 | "no-nested-ternary": 0, 30 | "react/destructuring-assignment": 0, 31 | "react/jsx-sort-props": [ 32 | 1, 33 | { 34 | "shorthandLast": true 35 | } 36 | ], 37 | "sort-imports": [ 38 | 1, 39 | { 40 | "ignoreCase": true, 41 | "ignoreDeclarationSort": true 42 | } 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | /.vscode 26 | .eslintcache 27 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "singleQuote": true, 4 | "trailingComma": "es5" 5 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10-alpine 2 | ENV APP_DIR /app 3 | WORKDIR ${APP_DIR} 4 | 5 | # Cache package.json 6 | COPY package.json package-lock.json ${APP_DIR}/ 7 | 8 | # Install dependencies 9 | RUN npm install 10 | 11 | # Add complete project structure 12 | COPY . ${APP_DIR} 13 | 14 | # Run the application 15 | ENTRYPOINT npm start 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > A search tool designed to help you find open source projects 6 | 7 | ## Demo & Usage 8 | 9 | - Use the toggle switches to filter results. Optionally enter text keywords 10 | - Click a title to open the issue on GitHub in a new tab 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Background 15 | 16 | The idea for this project comes from wanting to find cool projects on GitHub but not being satisfied with GitHub's native search. 17 | 18 | I began searching issues during [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (an annual event sponsored by Digital Ocean which encourages developers to get involved with open source. Make 4 PRs in a month and get a FREE T-shirt 👕). 19 | 20 | ## Local Development 21 | 22 | To run this project for local development if you have Node.js and NPM 23 | installed follow these steps in a terminal. The app will run on port 3000. 24 | 25 | ```bash 26 | npm install 27 | npm start 28 | ``` 29 | 30 | If you don't want to install Node.js and you have Docker present on your 31 | system, then just use the `Dockerfile` and the script that prepares 32 | the whole application in a separate container. The app will run on port 3000. 33 | 34 | ```bash 35 | ./dev.sh 36 | ``` 37 | 38 | ## Contributing 39 | 40 | Thank you for your interest! All types of contributions welcome. **HACK AWAY!** 🔨🔨🔨 41 | 42 | - Fork and clone this repository 43 | - Create your branch from the `master` branch 44 | - Please open your PR with the `master` branch as the base 45 | - Take a look at the PR checks to make sure the Netlify deploy preview looks correct 46 | 47 | -------------------------------------------------------------------------------- /dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -xe 3 | 4 | IMAGE_NAME="issue-collab" 5 | 6 | docker build --tag ${IMAGE_NAME} --file Dockerfile . 7 | docker rm --force ${IMAGE_NAME}-cont || true 8 | docker run \ 9 | --interactive \ 10 | --tty \ 11 | --name ${IMAGE_NAME}-cont \ 12 | --publish 3000:3000 \ 13 | --volume $(pwd)/src:/app/src \ 14 | --volume $(pwd)/public:/app/public \ 15 | ${IMAGE_NAME} 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "issue-collab", 3 | "version": "1.8.0", 4 | "description": "Tool for finding open source projects on GitHub", 5 | "bugs": { 6 | "url": "https://github.com/trybick/issue-collab/issues" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/trybick/issue-collab" 11 | }, 12 | "keywords": [ 13 | "github", 14 | "issues", 15 | "search", 16 | "open-source" 17 | ], 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject", 23 | "lint:fix": "eslint --fix --ext .jsx,.js ." 24 | }, 25 | "eslintConfig": { 26 | "extends": "react-app" 27 | }, 28 | "browserslist": [ 29 | ">0.2%", 30 | "not dead", 31 | "not ie <= 11", 32 | "not op_mini all" 33 | ], 34 | "dependencies": { 35 | "@material-ui/core": "^4.5.1", 36 | "@material-ui/icons": "^4.9.1", 37 | "moment": "^2.22.2", 38 | "node-sass": "^4.14.1", 39 | "react": "^16.6.0", 40 | "react-dark-mode-toggle": "0.0.10", 41 | "react-dom": "^16.6.0", 42 | "react-ga4": "^2.1.0", 43 | "react-scripts": "^2.1.3", 44 | "react-spinners": "^0.9.0", 45 | "react-toggle": "^4.0.2" 46 | }, 47 | "devDependencies": { 48 | "@babel/plugin-proposal-class-properties": "^7.4.4", 49 | "eslint": "^5.3.0", 50 | "eslint-config-airbnb": "^17.1.0", 51 | "eslint-config-prettier": "^4.2.0", 52 | "eslint-plugin-import": "^2.17.2", 53 | "eslint-plugin-jsx-a11y": "^6.2.1", 54 | "eslint-plugin-prettier": "^3.0.1", 55 | "eslint-plugin-react": "^7.12.4", 56 | "husky": "^4.3.0", 57 | "lint-staged": "^10.4.2", 58 | "prettier": "^1.17.0" 59 | }, 60 | "husky": { 61 | "hooks": { 62 | "pre-commit": "lint-staged" 63 | } 64 | }, 65 | "lint-staged": { 66 | "*.{jsx,js}": "eslint --cache --fix" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trybick/issue-collab/b183d83bd781dc98f0471a08c40a50e6eb75c8a0/public/favicon.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Issue Collab 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 |
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Issue Collab", 3 | "name": "Issue Collab", 4 | "icons": [ 5 | { 6 | "src": "favicon.png", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#f8f8f8" 15 | } 16 | -------------------------------------------------------------------------------- /public/meta-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trybick/issue-collab/b183d83bd781dc98f0471a08c40a50e6eb75c8a0/public/meta-logo.png -------------------------------------------------------------------------------- /src/components/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactGA from 'react-ga4'; 3 | import { getIsDarkModeEnabled, setLocalStorageItem } from '../utils/localStorage'; 4 | import { formatLabelsForUrl, formatTextToSearch, joinItemsForUrl } from '../utils/formatting'; 5 | import { baseUrl, gAnalyticsID, sortOptions } from '../utils/constants'; 6 | import Header from './core/Header'; 7 | import SearchContainer from './search/SearchContainer'; 8 | import TogglesContainer from './toggles/TogglesContainer'; 9 | import LoadingSpinner from './statuses/LoadingSpinner'; 10 | import InitialGreeting from './statuses/InitialGreeting'; 11 | import SearchResultsContainer from './search/SearchResultsContainer'; 12 | import ScrollToTopButton from './scrollToTopButton/ScrollToTopButton'; 13 | import './App.scss'; 14 | 15 | class App extends React.Component { 16 | state = { 17 | labels: { 18 | hacktoberfest: false, 19 | goodFirstIssue: false, 20 | helpWanted: false, 21 | documentation: false, 22 | bug: false, 23 | react: false, 24 | }, 25 | languages: { 26 | python: false, 27 | javascript: false, 28 | php: false, 29 | java: false, 30 | ruby: false, 31 | swift: false, 32 | }, 33 | fetchError: false, 34 | isEmpty: true, 35 | isFetching: false, 36 | results: {}, 37 | textToSearch: '', 38 | pageNum: 1, 39 | isButtonLocked: false, 40 | darkMode: false, 41 | }; 42 | 43 | componentDidMount = () => { 44 | ReactGA.initialize(gAnalyticsID); 45 | 46 | const isDarkModeEnabled = getIsDarkModeEnabled(); 47 | this.enableOrDisabledDarkModeStyling(isDarkModeEnabled); 48 | this.setState({ darkMode: isDarkModeEnabled }); 49 | }; 50 | 51 | getActiveItems = type => { 52 | const items = this.state[type]; 53 | return Object.keys(items).filter(item => items[item]); 54 | }; 55 | 56 | createUrl = () => { 57 | const { textToSearch, pageNum } = this.state; 58 | const formattedText = formatTextToSearch(textToSearch); 59 | 60 | const activeLabels = this.getActiveItems('labels'); 61 | const formattedLabels = formatLabelsForUrl(activeLabels); 62 | const joinedLabels = joinItemsForUrl(formattedLabels, 'labels'); 63 | 64 | const activeLanguage = this.getActiveItems('languages'); 65 | const joinedLanguage = joinItemsForUrl(activeLanguage, 'languages'); 66 | 67 | return `${baseUrl}${formattedText}type:issue${joinedLabels}${joinedLanguage}${sortOptions}&page=${pageNum}`; 68 | }; 69 | 70 | handleErrors = res => { 71 | if (!res.ok) { 72 | this.setState({ fetchError: true, isFetching: false }); 73 | throw Error(res.status); 74 | } 75 | return res.json(); 76 | }; 77 | 78 | getIssues = async (e, shouldResetPageNum = true) => { 79 | if (e) e.preventDefault(); 80 | 81 | const { isButtonLocked } = this.state; 82 | if (isButtonLocked) return; 83 | 84 | const preFetchState = { 85 | isEmpty: true, 86 | isFetching: true, 87 | isButtonLocked: true, 88 | }; 89 | if (shouldResetPageNum) { 90 | preFetchState.pageNum = 1; 91 | } 92 | await this.setState(preFetchState); 93 | 94 | const finalUrl = this.createUrl(); 95 | await fetch(finalUrl) 96 | .then(this.handleErrors) 97 | .then(resJson => { 98 | this.setState( 99 | { 100 | isEmpty: false, 101 | isFetching: false, 102 | results: resJson, 103 | }, 104 | () => 105 | setTimeout(() => { 106 | this.setState({ isButtonLocked: false }); 107 | }, 3000) 108 | ); 109 | }) 110 | .catch(() => { 111 | this.setState({ fetchError: true, isFetching: false, isButtonLocked: false }); 112 | }); 113 | }; 114 | 115 | handleTextChange = e => { 116 | this.setState({ textToSearch: e.target.value }); 117 | }; 118 | 119 | handlePageChange = (e, pageNum) => { 120 | e.preventDefault(); 121 | e.persist(); 122 | 123 | this.setState( 124 | { 125 | pageNum, 126 | isButtonLocked: false, 127 | }, 128 | () => { 129 | this.getIssues(e, false); 130 | } 131 | ); 132 | }; 133 | 134 | toggleLanguage = selectedName => { 135 | const currentLanguages = this.state.languages; 136 | Object.keys(currentLanguages).forEach(key => { 137 | if (key === selectedName) { 138 | currentLanguages[key] = !currentLanguages[key]; 139 | } else { 140 | currentLanguages[key] = false; 141 | } 142 | }); 143 | return currentLanguages; 144 | }; 145 | 146 | onToggleChange = event => { 147 | const { labels } = this.state; 148 | const selectedType = event.target.dataset.type; 149 | const selectedName = event.target.name; 150 | 151 | if (selectedType === 'label') { 152 | this.setState({ 153 | labels: { ...labels, [selectedName]: !labels[selectedName] }, 154 | }); 155 | } else if (selectedType === 'language') { 156 | const updatedLanguages = this.toggleLanguage(selectedName); 157 | this.setState({ 158 | languages: { ...updatedLanguages }, 159 | }); 160 | } 161 | }; 162 | 163 | onToggleDarkMode = isEnabled => { 164 | if (isEnabled) { 165 | this.setState({ darkMode: true }); 166 | setLocalStorageItem('dark-mode', 'true'); 167 | } else { 168 | this.setState({ darkMode: false }); 169 | setLocalStorageItem('dark-mode', 'false'); 170 | } 171 | this.enableOrDisabledDarkModeStyling(isEnabled); 172 | }; 173 | 174 | enableOrDisabledDarkModeStyling = isEnabled => { 175 | document.body.className = isEnabled ? 'dark-mode' : ''; 176 | }; 177 | 178 | resetToggles = toggleType => { 179 | const currentItems = this.state[toggleType]; 180 | Object.keys(currentItems).forEach(key => { 181 | currentItems[key] = false; 182 | }); 183 | return currentItems; 184 | }; 185 | 186 | onReset = () => { 187 | const resetLabels = this.resetToggles('labels'); 188 | const resetLanguages = this.resetToggles('languages'); 189 | this.setState({ 190 | labels: { ...resetLabels }, 191 | languages: { ...resetLanguages }, 192 | fetchError: false, 193 | isEmpty: true, 194 | isLoading: false, 195 | results: {}, 196 | textToSearch: '', 197 | pageNum: 1, 198 | isButtonLocked: false, 199 | }); 200 | }; 201 | 202 | render() { 203 | const { 204 | fetchError, 205 | isButtonLocked, 206 | isEmpty, 207 | isFetching, 208 | labels, 209 | languages, 210 | pageNum, 211 | results, 212 | textToSearch, 213 | darkMode, 214 | } = this.state; 215 | 216 | return ( 217 |
218 |
219 | 224 | 231 | 232 | {isEmpty ? ( 233 | isFetching ? ( 234 | 235 | ) : ( 236 | 237 | ) 238 | ) : ( 239 | 244 | )} 245 | 246 |
247 | ); 248 | } 249 | } 250 | 251 | export default App; 252 | -------------------------------------------------------------------------------- /src/components/App.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Lato|Roboto+Mono&display=swap'); 2 | @import '../styles/variables'; 3 | @import '../styles/normalize'; 4 | 5 | body { 6 | font-family: 'Lato', sans-serif; 7 | 8 | h3, 9 | h4 { 10 | font-weight: 400; 11 | } 12 | } 13 | 14 | .app-wrapper { 15 | max-width: 800px; 16 | margin: 0 auto; 17 | } 18 | 19 | .dark-mode{ 20 | background: #222; 21 | color: white; 22 | 23 | input, fieldset{ 24 | border-color: white; 25 | color: white; 26 | } 27 | 28 | .result-wrapper{ 29 | background: #888; 30 | 31 | .result-header{ 32 | color: lightblue; 33 | } 34 | 35 | .result-body{ 36 | color: white; 37 | 38 | .metadata{ 39 | color: white; 40 | } 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/components/core/Chip.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Chip.scss'; 3 | import { getContrastTextColor } from '../../utils/color'; 4 | 5 | const Chip = ({ text, color }) => { 6 | const dinStyle = { 7 | backgroundColor: `#${color}`, 8 | color: getContrastTextColor(color), 9 | }; 10 | 11 | return ( 12 | 13 | {text} 14 | 15 | ); 16 | }; 17 | 18 | export default Chip; 19 | -------------------------------------------------------------------------------- /src/components/core/Chip.scss: -------------------------------------------------------------------------------- 1 | .chip { 2 | display: inline-block; 3 | padding: .4em .6em; 4 | margin-right: .5em; 5 | border-radius: .2em; 6 | margin-top: 10px; 7 | min-width: 30px; 8 | text-align: center; 9 | } -------------------------------------------------------------------------------- /src/components/core/Header.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import DarkModeToggle from 'react-dark-mode-toggle'; 3 | import './Header.scss'; 4 | import githubIcon from '../../images/github-icon.svg'; 5 | import githubIconWhite from '../../images/github-icon-white.svg'; 6 | 7 | const Header = ({ onToggleDarkMode, darkMode }) => ( 8 |
9 |

10 | Issue-Collab 11 |

12 | 13 |
14 | 20 | 26 | github-icon 31 | 32 |
33 |
34 | ); 35 | 36 | export default Header; 37 | -------------------------------------------------------------------------------- /src/components/core/Header.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .page-header { 4 | margin: 30px auto 25px; 5 | padding: 0 10px 15px; 6 | text-align: center; 7 | border-bottom: 2px solid grey; 8 | 9 | display: flex; 10 | justify-content: space-between; 11 | align-items: center; 12 | 13 | &-title { 14 | font-family: 'Roboto Mono', monospace; 15 | font-size: 2em; 16 | padding-bottom: 6px; 17 | margin: 0; 18 | 19 | &-highlight { 20 | color: $color10; 21 | } 22 | } 23 | } 24 | 25 | .header-right { 26 | display: flex; 27 | flex-direction: row; 28 | } 29 | 30 | .github-link { 31 | height: 18px; 32 | width: 50px; 33 | text-align: right; 34 | 35 | .github-svg { 36 | cursor: pointer; 37 | width: 60%; 38 | } 39 | } 40 | 41 | .dark-mode-toggle { 42 | margin-top: 5px; 43 | } 44 | -------------------------------------------------------------------------------- /src/components/core/Pagination.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Pagination.scss'; 3 | import Button from '@material-ui/core/Button'; 4 | 5 | const Pagination = ({ totalPages = 1, currentPage = 1, onPageChange }) => { 6 | const handleClickPrev = e => { 7 | const pageNum = currentPage > 1 ? currentPage - 1 : 1; 8 | onPageChange(e, pageNum); 9 | }; 10 | 11 | const handleClickNext = e => { 12 | const pageNum = currentPage < totalPages ? currentPage + 1 : totalPages; 13 | onPageChange(e, pageNum); 14 | }; 15 | 16 | return ( 17 |
18 | {currentPage !== 1 && ( 19 | 27 | )} 28 |
29 | Page {currentPage} of {totalPages.toLocaleString()} 30 |
31 | 39 |
40 | ); 41 | }; 42 | 43 | export default Pagination; 44 | -------------------------------------------------------------------------------- /src/components/core/Pagination.scss: -------------------------------------------------------------------------------- 1 | .pagination { 2 | padding: 30px 15px 40px; 3 | display: flex; 4 | flex-direction: row; 5 | justify-content: space-between; 6 | 7 | .page-count { 8 | text-align: center; 9 | margin: 0 auto; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/components/scrollToTopButton/ScrollToTopButton.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Fab } from '@material-ui/core'; 3 | import ArrowUpIcon from '@material-ui/icons/ArrowUpward'; 4 | import './ScrollToTopButton.scss'; 5 | 6 | const ScrollToTopButton = () => { 7 | const [showScroll, setShowScroll] = useState(false); 8 | 9 | const getShouldShowButton = () => { 10 | window.pageYOffset > 500 ? setShowScroll(true) : setShowScroll(false); 11 | }; 12 | 13 | const scrollToTop = () => { 14 | window.scrollTo({ top: 0, behavior: 'smooth' }); 15 | }; 16 | 17 | useEffect(() => { 18 | window.addEventListener('scroll', getShouldShowButton); 19 | return () => { 20 | window.removeEventListener('scroll', getShouldShowButton); 21 | }; 22 | }, []); 23 | 24 | return ( 25 |
26 | {showScroll && ( 27 |
28 | 29 | 30 | 31 |
32 | )} 33 |
34 | ); 35 | }; 36 | 37 | export default ScrollToTopButton; 38 | -------------------------------------------------------------------------------- /src/components/scrollToTopButton/ScrollToTopButton.scss: -------------------------------------------------------------------------------- 1 | .scroll-to-top{ 2 | position: fixed; 3 | width: 56px; 4 | height: 56px; 5 | bottom: 4%; 6 | right: 2%; 7 | z-index: 1000; 8 | } 9 | 10 | @media only screen and (max-width: 1000px) { 11 | .scroll-to-top{ 12 | bottom: 11%; 13 | right: 7.5%; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/components/search/SearchContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Button from '@material-ui/core/Button'; 3 | import TextField from '@material-ui/core/TextField'; 4 | import './SearchContainer.scss'; 5 | 6 | const SearchContainer = ({ 7 | handleTextChange, 8 | textToSearch, 9 | isGetButtonDisabled, 10 | getIssues, 11 | onReset, 12 | }) => { 13 | const listenForSubmit = e => { 14 | if (e.key === 'Enter') { 15 | getIssues(); 16 | } 17 | }; 18 | 19 | return ( 20 |
21 |
22 | listenForSubmit(e)} 34 | placeholder="Enter keywords (optional)" 35 | type="text" 36 | value={textToSearch} 37 | variant="outlined" 38 | /> 39 |
40 |
41 | 52 | 61 |
62 |
63 | ); 64 | }; 65 | 66 | export default SearchContainer; 67 | -------------------------------------------------------------------------------- /src/components/search/SearchContainer.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .search-container { 4 | &-input { 5 | text-align: center; 6 | 7 | &-field { 8 | width: 225px; 9 | } 10 | } 11 | 12 | .button-group { 13 | text-align: center; 14 | margin: 20px 0 30px; 15 | 16 | .get-btn { 17 | margin-right: 10px !important; 18 | background-color: $color10 !important; 19 | } 20 | 21 | .reset-btn { 22 | margin-left: 10px !important; 23 | background-color: $color12; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/components/search/SearchResult.jsx: -------------------------------------------------------------------------------- 1 | import './SearchResult.scss'; 2 | 3 | import React, { useState } from 'react'; 4 | import Chip from '../core/Chip'; 5 | 6 | export const SearchResult = ({ 7 | user, 8 | htmlUrl, 9 | title, 10 | bodyText, 11 | userName, 12 | repoName, 13 | issueAge, 14 | numComments, 15 | labels, 16 | }) => { 17 | const [hasBeenClicked, setClicked] = useState(false); 18 | 19 | const labelChips = labels.map(({ id, name, color }) => { 20 | return ; 21 | }); 22 | 23 | return ( 24 |
25 |
26 | avatar 27 | 28 | setClicked(true)} 32 | rel="noopener noreferrer" 33 | target="_blank" 34 | > 35 | {title} 36 | 37 |
38 |
39 |

{bodyText}

40 | 41 |
42 |
{`${userName}/${repoName}`}
43 |
{issueAge}
44 |
{`${numComments} comments`}
45 |
46 | 47 |
{labelChips}
48 |
49 |
50 | ); 51 | }; 52 | -------------------------------------------------------------------------------- /src/components/search/SearchResult.scss: -------------------------------------------------------------------------------- 1 | .result-wrapper { 2 | padding: 1em; 3 | margin: 0.75em 0 2em; 4 | background-color: #ffffff; 5 | box-shadow: -1px 2px 4px rgba(0, 0, 0, 0.25), 1px 1px 3px rgba(0, 0, 0, 0.1); 6 | border-radius: 14px; 7 | font-family: 'Lato', sans-serif; 8 | 9 | &.clicked { 10 | opacity: 0.55; 11 | } 12 | 13 | .result-header { 14 | display: flex; 15 | align-items: center; 16 | 17 | .avatar { 18 | width: 3em; 19 | border-radius: 1.5em; 20 | margin-right: 1em; 21 | } 22 | 23 | .link-title { 24 | font-family: 'Roboto Mono', monospace; 25 | text-decoration: underline; 26 | font-size: 1.4rem; 27 | } 28 | } 29 | 30 | .result-body { 31 | padding-left: 5px; 32 | 33 | .body-text { 34 | font-size: 0.9rem; 35 | line-height: 1.4em; 36 | max-width: 800px; 37 | overflow-wrap: break-word; 38 | } 39 | 40 | .metadata { 41 | font-family: 'Roboto Mono', monospace; 42 | margin: 0.2em 0; 43 | color: #757575; 44 | 45 | .issue-age { 46 | font-size: 0.7rem; 47 | margin-top: -8px; 48 | } 49 | } 50 | 51 | .label-chips { 52 | margin: 5px 0 5px; 53 | } 54 | 55 | .comments { 56 | font-size: 0.7rem; 57 | margin-top: -13px; 58 | } 59 | } 60 | } 61 | 62 | .dark-mode{ 63 | .result-wrapper{ 64 | background: #ffffff0f; 65 | box-shadow: -1px 2px 4px rgb(31,31,31), 1px 1px 3px rgba(0,0,0,.1); 66 | .result-header{ 67 | a{ 68 | color: #4e7fef; 69 | } 70 | .link-title{ 71 | color: #ffffff 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/components/search/SearchResultsContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import moment from 'moment'; 3 | import Pagination from '../core/Pagination'; 4 | import NoResultsMessage from '../statuses/NoResultsMessage'; 5 | import { resultPerPage } from '../../utils/constants'; 6 | import { SearchResult } from './SearchResult'; 7 | import './SearchResultsContainer.scss'; 8 | 9 | const SearchResultsContainer = ({ currentPage, onPageChange, results }) => { 10 | const totalPages = Math.ceil(results.total_count / resultPerPage); 11 | 12 | const resultsContainerHeader = results.total_count > 0 && ( 13 |
14 |

15 | Issues Found: 16 | {results.total_count.toLocaleString()} 17 |

18 |
19 | ); 20 | 21 | const formattedResults = 22 | results.items[0] && 23 | results.items.map(item => { 24 | const htmlUrl = item.html_url.split('/'); 25 | const userName = htmlUrl[3]; 26 | const repoName = htmlUrl[4]; 27 | const issueAge = moment(item.created_at).fromNow(); 28 | const { comments: numComments } = item; 29 | 30 | let bodyText = No additional text; 31 | if (item.body) { 32 | if (item.body.length < 300) { 33 | bodyText = item.body; 34 | } else if (item.body.length > 300) { 35 | bodyText = `${item.body.substr(0, 300)}...`; 36 | } 37 | } 38 | 39 | return ( 40 | 52 | ); 53 | }); 54 | 55 | return ( 56 |
57 | {resultsContainerHeader} 58 | {formattedResults} 59 | {results.total_count === 0 && } 60 | {totalPages > 1 && ( 61 | 62 | )} 63 |
64 | ); 65 | }; 66 | 67 | export default SearchResultsContainer; 68 | -------------------------------------------------------------------------------- /src/components/search/SearchResultsContainer.scss: -------------------------------------------------------------------------------- 1 | .results-container { 2 | max-width: 800px; 3 | font-family: 'Roboto Mono', monospace; 4 | line-height: 2em; 5 | margin: 0 auto; 6 | 7 | @media only screen and (max-width: 800px) { 8 | max-width: 90vw; 9 | } 10 | 11 | &-header { 12 | display: flex; 13 | justify-content: space-between; 14 | align-items: center; 15 | } 16 | 17 | .issues-count { 18 | font-size: 1.2em; 19 | 20 | &-number { 21 | font-weight: bold; 22 | color: #3498db; 23 | padding-left: 0.8em; 24 | } 25 | } 26 | 27 | .no-text-message { 28 | font-style: italic; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/components/statuses/InitialGreeting.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import logo from '../../images/greeting-icon.png'; 3 | import './InitialGreeting.scss'; 4 | 5 | const InitialGreeting = ({ hasError }) => { 6 | const statusMessage = hasError ? ( 7 |

Oops, that was an error.

8 | ) : ( 9 |
10 | 11 |

12 | Use the toggles above to filter by common issue labels and by your favorite{' '} 13 | programming languages. You can also search by keyword! 14 |

15 |

16 | Click Find Issues and get collaborating! 17 |

18 |
19 | issue-collab-logo 20 |
21 | ); 22 | 23 | return
{statusMessage}
; 24 | }; 25 | 26 | export default InitialGreeting; 27 | -------------------------------------------------------------------------------- /src/components/statuses/InitialGreeting.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .greeting-card-wrapper { 4 | text-align: center; 5 | margin: 50px 0; 6 | 7 | p { 8 | font-weight: 300; 9 | 10 | b { 11 | font-family: 'Roboto Mono', monospace; 12 | } 13 | } 14 | 15 | &::before { 16 | font-family: 'Roboto Mono'; 17 | content: '*'; 18 | font-size: 4em; 19 | float: left; 20 | position: relative; 21 | left: 105px; 22 | line-height: 0; 23 | color: $color10; 24 | margin: 0; 25 | padding: 0; 26 | } 27 | } 28 | 29 | .greeting-card { 30 | display: grid; 31 | grid-template-columns: 5fr 1fr; 32 | width: 75%; 33 | font-size: 0.98em; 34 | background: rgba(255, 255, 255, 0.5); 35 | box-shadow: -1px 2px 14px rgba(0, 0, 0, 0.25), 1px 1px 3px rgba(0, 0, 0, 0.1); 36 | border-radius: 5px; 37 | box-sizing: border-box; 38 | margin: 0 auto; 39 | padding: 1em; 40 | overflow: auto; 41 | 42 | em { 43 | font-style: normal; 44 | line-height: 1.2rem; 45 | } 46 | 47 | .greeting-img { 48 | width: auto; 49 | height: 6rem; 50 | } 51 | } 52 | 53 | .dark-mode{ 54 | .greeting-card{ 55 | background: #ffffff05; 56 | box-shadow: -1px 2px 14px #948d8d00, 1px 1px 3px #7d77770f; 57 | } 58 | } -------------------------------------------------------------------------------- /src/components/statuses/LoadingSpinner.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PulseLoader from 'react-spinners/PulseLoader'; 3 | import './LoadingSpinner.scss'; 4 | 5 | const LoadingSpinner = ({ darkMode }) => { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | }; 12 | 13 | export default LoadingSpinner; 14 | -------------------------------------------------------------------------------- /src/components/statuses/LoadingSpinner.scss: -------------------------------------------------------------------------------- 1 | .loading-spinner-wrapper { 2 | text-align: center; 3 | margin-top: 65px; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/statuses/NoResultsMessage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const NoResultsMessage = () => { 4 | return ( 5 |
6 |

No results found

7 |
Try searching for a maximum of 2-3 labels
8 |
9 | ); 10 | }; 11 | 12 | export default NoResultsMessage; 13 | -------------------------------------------------------------------------------- /src/components/toggles/Labels.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ToggleGroup from './ToggleGroup'; 3 | 4 | const Labels = ({ onToggleChange, labels }) => { 5 | return ( 6 |
7 |

Labels:

8 | 14 |
15 | ); 16 | }; 17 | 18 | export default Labels; 19 | -------------------------------------------------------------------------------- /src/components/toggles/Languages.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ToggleGroup from './ToggleGroup'; 3 | 4 | const Languages = ({ onToggleChange, languages }) => { 5 | return ( 6 |
7 |

Languages:

8 | 14 |
15 | ); 16 | }; 17 | 18 | export default Languages; 19 | -------------------------------------------------------------------------------- /src/components/toggles/ToggleGroup.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Toggle from 'react-toggle'; 3 | import { formatLabelForName } from '../../utils/formatting'; 4 | import '../../styles/react-toggle.scss'; 5 | 6 | const ToggleGroup = ({ dataType, items, onToggleChange, names }) => { 7 | const mappedToggles = names.map(name => { 8 | return ( 9 |
10 | 17 | {formatLabelForName(name)} 18 |
19 | ); 20 | }); 21 | 22 | return mappedToggles; 23 | }; 24 | 25 | export default ToggleGroup; 26 | -------------------------------------------------------------------------------- /src/components/toggles/TogglesContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Labels from './Labels'; 3 | import Languages from './Languages'; 4 | import './TogglesContainer.scss'; 5 | 6 | const TogglesContainer = ({ labels, languages, onToggleChange }) => ( 7 |
8 | 9 | 10 |
11 | ); 12 | 13 | export default TogglesContainer; 14 | -------------------------------------------------------------------------------- /src/components/toggles/TogglesContainer.scss: -------------------------------------------------------------------------------- 1 | .toggles-container { 2 | display: flex; 3 | justify-content: space-around; 4 | margin: 0 0 40px; 5 | } 6 | -------------------------------------------------------------------------------- /src/images/github-icon-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/github-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/greeting-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trybick/issue-collab/b183d83bd781dc98f0471a08c40a50e6eb75c8a0/src/images/greeting-icon.png -------------------------------------------------------------------------------- /src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './components/App'; 4 | 5 | ReactDOM.render(, document.getElementById('root')); 6 | -------------------------------------------------------------------------------- /src/styles/_normalize.scss: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in iOS. 9 | */ 10 | 11 | html { 12 | line-height: 1.15; /* 1 */ 13 | -webkit-text-size-adjust: 100%; /* 2 */ 14 | } 15 | 16 | /* Sections 17 | ========================================================================== */ 18 | 19 | /** 20 | * Remove the margin in all browsers. 21 | */ 22 | 23 | body { 24 | margin: 0; 25 | } 26 | 27 | /** 28 | * Render the `main` element consistently in IE. 29 | */ 30 | 31 | main { 32 | display: block; 33 | } 34 | 35 | /** 36 | * Correct the font size and margin on `h1` elements within `section` and 37 | * `article` contexts in Chrome, Firefox, and Safari. 38 | */ 39 | 40 | h1 { 41 | font-size: 2em; 42 | margin: 0.67em 0; 43 | } 44 | 45 | /* Grouping content 46 | ========================================================================== */ 47 | 48 | /** 49 | * 1. Add the correct box sizing in Firefox. 50 | * 2. Show the overflow in Edge and IE. 51 | */ 52 | 53 | hr { 54 | box-sizing: content-box; /* 1 */ 55 | height: 0; /* 1 */ 56 | overflow: visible; /* 2 */ 57 | } 58 | 59 | /** 60 | * 1. Correct the inheritance and scaling of font size in all browsers. 61 | * 2. Correct the odd `em` font sizing in all browsers. 62 | */ 63 | 64 | pre { 65 | font-family: monospace, monospace; /* 1 */ 66 | font-size: 1em; /* 2 */ 67 | } 68 | 69 | /* Text-level semantics 70 | ========================================================================== */ 71 | 72 | /** 73 | * Remove the gray background on active links in IE 10. 74 | */ 75 | 76 | a { 77 | background-color: transparent; 78 | } 79 | 80 | /** 81 | * 1. Remove the bottom border in Chrome 57- 82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 83 | */ 84 | 85 | abbr[title] { 86 | border-bottom: none; /* 1 */ 87 | text-decoration: underline; /* 2 */ 88 | text-decoration: underline dotted; /* 2 */ 89 | } 90 | 91 | /** 92 | * Add the correct font weight in Chrome, Edge, and Safari. 93 | */ 94 | 95 | b, 96 | strong { 97 | font-weight: bolder; 98 | } 99 | 100 | /** 101 | * 1. Correct the inheritance and scaling of font size in all browsers. 102 | * 2. Correct the odd `em` font sizing in all browsers. 103 | */ 104 | 105 | code, 106 | kbd, 107 | samp { 108 | font-family: monospace, monospace; /* 1 */ 109 | font-size: 1em; /* 2 */ 110 | } 111 | 112 | /** 113 | * Add the correct font size in all browsers. 114 | */ 115 | 116 | small { 117 | font-size: 80%; 118 | } 119 | 120 | /** 121 | * Prevent `sub` and `sup` elements from affecting the line height in 122 | * all browsers. 123 | */ 124 | 125 | sub, 126 | sup { 127 | font-size: 75%; 128 | line-height: 0; 129 | position: relative; 130 | vertical-align: baseline; 131 | } 132 | 133 | sub { 134 | bottom: -0.25em; 135 | } 136 | 137 | sup { 138 | top: -0.5em; 139 | } 140 | 141 | /* Embedded content 142 | ========================================================================== */ 143 | 144 | /** 145 | * Remove the border on images inside links in IE 10. 146 | */ 147 | 148 | img { 149 | border-style: none; 150 | } 151 | 152 | /* Forms 153 | ========================================================================== */ 154 | 155 | /** 156 | * 1. Change the font styles in all browsers. 157 | * 2. Remove the margin in Firefox and Safari. 158 | */ 159 | 160 | button, 161 | input, 162 | optgroup, 163 | select, 164 | textarea { 165 | font-family: inherit; /* 1 */ 166 | font-size: 100%; /* 1 */ 167 | line-height: 1.15; /* 1 */ 168 | margin: 0; /* 2 */ 169 | } 170 | 171 | /** 172 | * Show the overflow in IE. 173 | * 1. Show the overflow in Edge. 174 | */ 175 | 176 | button, 177 | input { 178 | /* 1 */ 179 | overflow: visible; 180 | } 181 | 182 | /** 183 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 184 | * 1. Remove the inheritance of text transform in Firefox. 185 | */ 186 | 187 | button, 188 | select { 189 | /* 1 */ 190 | text-transform: none; 191 | } 192 | 193 | /** 194 | * Correct the inability to style clickable types in iOS and Safari. 195 | */ 196 | 197 | button, 198 | [type='button'], 199 | [type='reset'], 200 | [type='submit'] { 201 | -webkit-appearance: button; 202 | } 203 | 204 | /** 205 | * Remove the inner border and padding in Firefox. 206 | */ 207 | 208 | button::-moz-focus-inner, 209 | [type='button']::-moz-focus-inner, 210 | [type='reset']::-moz-focus-inner, 211 | [type='submit']::-moz-focus-inner { 212 | border-style: none; 213 | padding: 0; 214 | } 215 | 216 | /** 217 | * Restore the focus styles unset by the previous rule. 218 | */ 219 | 220 | button:-moz-focusring, 221 | [type='button']:-moz-focusring, 222 | [type='reset']:-moz-focusring, 223 | [type='submit']:-moz-focusring { 224 | outline: 1px dotted ButtonText; 225 | } 226 | 227 | /** 228 | * Correct the padding in Firefox. 229 | */ 230 | 231 | fieldset { 232 | padding: 0.35em 0.75em 0.625em; 233 | } 234 | 235 | /** 236 | * 1. Correct the text wrapping in Edge and IE. 237 | * 2. Correct the color inheritance from `fieldset` elements in IE. 238 | * 3. Remove the padding so developers are not caught out when they zero out 239 | * `fieldset` elements in all browsers. 240 | */ 241 | 242 | legend { 243 | box-sizing: border-box; /* 1 */ 244 | color: inherit; /* 2 */ 245 | display: table; /* 1 */ 246 | max-width: 100%; /* 1 */ 247 | padding: 0; /* 3 */ 248 | white-space: normal; /* 1 */ 249 | } 250 | 251 | /** 252 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 253 | */ 254 | 255 | progress { 256 | vertical-align: baseline; 257 | } 258 | 259 | /** 260 | * Remove the default vertical scrollbar in IE 10+. 261 | */ 262 | 263 | textarea { 264 | overflow: auto; 265 | } 266 | 267 | /** 268 | * 1. Add the correct box sizing in IE 10. 269 | * 2. Remove the padding in IE 10. 270 | */ 271 | 272 | [type='checkbox'], 273 | [type='radio'] { 274 | box-sizing: border-box; /* 1 */ 275 | padding: 0; /* 2 */ 276 | } 277 | 278 | /** 279 | * Correct the cursor style of increment and decrement buttons in Chrome. 280 | */ 281 | 282 | [type='number']::-webkit-inner-spin-button, 283 | [type='number']::-webkit-outer-spin-button { 284 | height: auto; 285 | } 286 | 287 | /** 288 | * 1. Correct the odd appearance in Chrome and Safari. 289 | * 2. Correct the outline style in Safari. 290 | */ 291 | 292 | [type='search'] { 293 | -webkit-appearance: textfield; /* 1 */ 294 | outline-offset: -2px; /* 2 */ 295 | } 296 | 297 | /** 298 | * Remove the inner padding in Chrome and Safari on macOS. 299 | */ 300 | 301 | [type='search']::-webkit-search-decoration { 302 | -webkit-appearance: none; 303 | } 304 | 305 | /** 306 | * 1. Correct the inability to style clickable types in iOS and Safari. 307 | * 2. Change font properties to `inherit` in Safari. 308 | */ 309 | 310 | ::-webkit-file-upload-button { 311 | -webkit-appearance: button; /* 1 */ 312 | font: inherit; /* 2 */ 313 | } 314 | 315 | /* Interactive 316 | ========================================================================== */ 317 | 318 | /* 319 | * Add the correct display in Edge, IE 10+, and Firefox. 320 | */ 321 | 322 | details { 323 | display: block; 324 | } 325 | 326 | /* 327 | * Add the correct display in all browsers. 328 | */ 329 | 330 | summary { 331 | display: list-item; 332 | } 333 | 334 | /* Misc 335 | ========================================================================== */ 336 | 337 | /** 338 | * Add the correct display in IE 10+. 339 | */ 340 | 341 | template { 342 | display: none; 343 | } 344 | 345 | /** 346 | * Add the correct display in IE 10. 347 | */ 348 | 349 | [hidden] { 350 | display: none; 351 | } 352 | -------------------------------------------------------------------------------- /src/styles/_variables.scss: -------------------------------------------------------------------------------- 1 | $color00: #fafafa; 2 | $color01: #eaece9; 3 | $color02: #bec3c9; 4 | $color03: #70f2fc; 5 | $color04: #f59e40; 6 | $color05: #5abc64; 7 | $color06: #56bcca; 8 | $color07: #ee7fb3; 9 | $color08: #f8f8f8; 10 | $color09: #3a5783; 11 | $color10: #3498db; 12 | $color11: #0000ee; 13 | $color12: #dc2b6a; 14 | -------------------------------------------------------------------------------- /src/styles/react-toggle.scss: -------------------------------------------------------------------------------- 1 | .react-toggle { 2 | touch-action: pan-x; 3 | 4 | display: inline-block; 5 | position: relative; 6 | cursor: pointer; 7 | background-color: transparent; 8 | border: 0; 9 | padding: 0; 10 | 11 | -webkit-touch-callout: none; 12 | -webkit-user-select: none; 13 | -khtml-user-select: none; 14 | -moz-user-select: none; 15 | -ms-user-select: none; 16 | user-select: none; 17 | 18 | -webkit-tap-highlight-color: rgba(0,0,0,0); 19 | -webkit-tap-highlight-color: transparent; 20 | } 21 | 22 | .react-toggle-screenreader-only { 23 | border: 0; 24 | clip: rect(0 0 0 0); 25 | height: 1px; 26 | margin: -1px; 27 | overflow: hidden; 28 | padding: 0; 29 | position: absolute; 30 | width: 1px; 31 | } 32 | 33 | .react-toggle--disabled { 34 | cursor: not-allowed; 35 | opacity: 0.5; 36 | -webkit-transition: opacity 0.25s; 37 | transition: opacity 0.25s; 38 | } 39 | 40 | .react-toggle-track { 41 | width: 50px; 42 | height: 24px; 43 | padding: 0; 44 | border-radius: 30px; 45 | background-color: #4D4D4D; 46 | -webkit-transition: all 0.2s ease; 47 | -moz-transition: all 0.2s ease; 48 | transition: all 0.2s ease; 49 | } 50 | 51 | .react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track { 52 | background-color: #000000; 53 | } 54 | 55 | .react-toggle--checked .react-toggle-track { 56 | background-color: #19AB27; 57 | } 58 | 59 | .react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track { 60 | background-color: #128D15; 61 | } 62 | 63 | .react-toggle-track-check { 64 | position: absolute; 65 | width: 14px; 66 | height: 10px; 67 | top: 0px; 68 | bottom: 0px; 69 | margin-top: auto; 70 | margin-bottom: auto; 71 | line-height: 0; 72 | left: 8px; 73 | opacity: 0; 74 | -webkit-transition: opacity 0.25s ease; 75 | -moz-transition: opacity 0.25s ease; 76 | transition: opacity 0.25s ease; 77 | } 78 | 79 | .react-toggle--checked .react-toggle-track-check { 80 | opacity: 1; 81 | -webkit-transition: opacity 0.25s ease; 82 | -moz-transition: opacity 0.25s ease; 83 | transition: opacity 0.25s ease; 84 | } 85 | 86 | .react-toggle-track-x { 87 | position: absolute; 88 | width: 10px; 89 | height: 10px; 90 | top: 0px; 91 | bottom: 0px; 92 | margin-top: auto; 93 | margin-bottom: auto; 94 | line-height: 0; 95 | right: 10px; 96 | opacity: 1; 97 | -webkit-transition: opacity 0.25s ease; 98 | -moz-transition: opacity 0.25s ease; 99 | transition: opacity 0.25s ease; 100 | } 101 | 102 | .react-toggle--checked .react-toggle-track-x { 103 | opacity: 0; 104 | } 105 | 106 | .react-toggle-thumb { 107 | transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0ms; 108 | position: absolute; 109 | top: 1px; 110 | left: 1px; 111 | width: 22px; 112 | height: 22px; 113 | border: 1px solid #4D4D4D; 114 | border-radius: 50%; 115 | background-color: #FAFAFA; 116 | 117 | -webkit-box-sizing: border-box; 118 | -moz-box-sizing: border-box; 119 | box-sizing: border-box; 120 | 121 | -webkit-transition: all 0.25s ease; 122 | -moz-transition: all 0.25s ease; 123 | transition: all 0.25s ease; 124 | } 125 | 126 | .react-toggle--checked .react-toggle-thumb { 127 | left: 27px; 128 | border-color: #19AB27; 129 | } 130 | 131 | .react-toggle--focus .react-toggle-thumb { 132 | -webkit-box-shadow: 0px 0px 3px 2px #0099E0; 133 | -moz-box-shadow: 0px 0px 3px 2px #0099E0; 134 | box-shadow: 0px 0px 2px 3px #0099E0; 135 | } 136 | 137 | .react-toggle:active:not(.react-toggle--disabled) .react-toggle-thumb { 138 | -webkit-box-shadow: 0px 0px 5px 5px #0099E0; 139 | -moz-box-shadow: 0px 0px 5px 5px #0099E0; 140 | box-shadow: 0px 0px 5px 5px #0099E0; 141 | } 142 | 143 | .toggle-label { 144 | margin-left: 6px; 145 | vertical-align: top; 146 | } -------------------------------------------------------------------------------- /src/utils/color.js: -------------------------------------------------------------------------------- 1 | export const getContrastTextColor = hexColor => { 2 | let color = hexColor; 3 | 4 | if (color.indexOf('#') === 0) { 5 | color = color.slice(1); 6 | } 7 | if (color.length === 3) { 8 | color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]; 9 | } 10 | if (color.length !== 6) { 11 | throw new Error('Invalid HexColor'); 12 | } 13 | 14 | const r = parseInt(color.slice(0, 2), 16); 15 | const g = parseInt(color.slice(2, 4), 16); 16 | const b = parseInt(color.slice(4, 6), 16); 17 | 18 | return (0.299 * r + 0.587 * g + 0.114 * b) / 255 > 0.5 ? '#000000' : '#ffffff'; 19 | }; 20 | -------------------------------------------------------------------------------- /src/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const baseUrl = 'https://api.github.com/search/issues?q='; 2 | export const resultPerPage = 20; 3 | export const sortOptions = `+state:open&sort=created&order=desc&per_page=${resultPerPage}`; 4 | export const gAnalyticsID = 'G-S4SCPLGLKY'; 5 | -------------------------------------------------------------------------------- /src/utils/formatting.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-extend-native */ 2 | String.prototype.camelToSpaces = function() { 3 | return this.replace(/([a-z])([A-Z])/g, '$1 $2'); 4 | }; 5 | 6 | String.prototype.addQuotes = function() { 7 | return `"${this}"`; 8 | }; 9 | 10 | function hasUpperCase(str) { 11 | return str.toLowerCase() !== str; 12 | } 13 | 14 | function hasWhiteSpace(str) { 15 | return str.indexOf(' ') >= 0; 16 | } 17 | 18 | export const formatLabelsForUrl = labels => { 19 | return labels.map(label => { 20 | if (!hasUpperCase(label)) { 21 | return label; 22 | } 23 | return label 24 | .camelToSpaces() 25 | .toLowerCase() 26 | .addQuotes(); 27 | }); 28 | }; 29 | 30 | export const formatTextToSearch = text => { 31 | if (text !== '') { 32 | if (hasWhiteSpace(text)) { 33 | return `${`${text}`.addQuotes()}+`; 34 | } 35 | return `${text}+`; 36 | } 37 | return ''; 38 | }; 39 | 40 | export const formatLabelForName = name => { 41 | return name.camelToSpaces().toLowerCase(); 42 | }; 43 | 44 | export const joinItemsForUrl = (items, itemType) => { 45 | return items.map(item => `+${itemType.slice(0, -1)}:${item}`).join(''); 46 | }; 47 | -------------------------------------------------------------------------------- /src/utils/localStorage.js: -------------------------------------------------------------------------------- 1 | const handleLocalStorageErrors = () => { 2 | console.error('LocalStorage is unavailable'); 3 | return null; 4 | }; 5 | 6 | export function setLocalStorageItem(name, value) { 7 | if (window.localStorage) { 8 | return window.localStorage.setItem(name, value); 9 | } 10 | return handleLocalStorageErrors(); 11 | } 12 | 13 | export function getLocalStorageItem(name) { 14 | if (window.localStorage) { 15 | return window.localStorage.getItem(name); 16 | } 17 | return handleLocalStorageErrors(); 18 | } 19 | 20 | export const getIsDarkModeEnabled = () => { 21 | return getLocalStorageItem('dark-mode') === 'true'; 22 | }; 23 | -------------------------------------------------------------------------------- /translations/README-Czech.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Vyhledávací nástroj, který Vám pomůže najít open source projekty 6 | 7 | ## Ukázka & Použití 8 | 9 | - Pomocí přepínačů můžete filtrovat výsledky. Volitelně lze zadat cílová slova. 10 | - Klikem na nadpis problému budete přesměrováni na stránku daného problému na Githubu na nové kartě prohlížeče 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Původ 15 | 16 | Myšlenkou projektu je najít super projekty na GitHubu. Nativní vyhledávání na GitHubu je ale neuspokojující. 17 | 18 | Začal jsem hledat problémy během [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (Každoroční projekt sponsorován Digital Ocean, který podporuje vývojáře, aby se zapojili do vývoje open source. Odměnou za 4 pull requesty je tričko zdarma 👕). 19 | 20 | ## Lokální vývoj 21 | 22 | Pokud máte naistalován Node.js a NPM tak pro spuštění projektu pro lokální vývoj následujte 23 | následující kroky. Applikace bude spustěna na portu 3000. 24 | 25 | ```bash 26 | npm install 27 | npm start 28 | ``` 29 | 30 | Pokud nechcete instalovat Node.js ale máte na svém systému Docker, použijte `Dockerfile`. 31 | Celá aplikace se spustí v samostatném kontejneru. 32 | Applikace bude spustěna na portu 3000. 33 | 34 | ```bash 35 | ./dev.sh 36 | ``` 37 | 38 | ## Přispívání 39 | 40 | Děkuji za Váš zájem. Všechny typy přispívání k tomuto projektu jsou vítány. **HACK AWAY!** 🔨🔨🔨 41 | 42 | - Forkněte a naklonujte repozitář 43 | - Vytvořte novou větev z `master` větve 44 | - Otevřete novou pull request z `master` větve 45 | - V náhledu na Netlify zkontrolujte zda pull request vypadá tak, jak má 46 | 47 | -------------------------------------------------------------------------------- /translations/README-French.md: -------------------------------------------------------------------------------- 1 | # Problème Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Un outil de recherche conçu pour vous aider à trouver des projets open source 6 | 7 | ## Démonstration et utilisation 8 | 9 | - Utilisez les interrupteurs à bascule pour filtrer les résultats. En option saisir des mots clés de texte 10 | - Cliquez sur un titre pour ouvrir le problème sur GitHub dans un nouvel onglet 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Contexte 15 | 16 | L'idée de ce projet vient du fait de vouloir trouver des projets sympas sur GitHub mais de ne pas se satisfaire de la recherche native de GitHub. 17 | 18 | J'ai commencé à rechercher des problèmes pendant [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (Un événement annuel sponsorisé par Digital Ocean qui encourage les développeurs à s'impliquer dans le domaine de l'open source. Faites 4 RP en un mois et recevez un T-shirt GRATUIT 👕). 19 | 20 | ## Développement local 21 | 22 | Pour exécuter ce projet pour le développement local si vous avez Node.js et NPM 23 | installé, suivez ces étapes dans un terminal. 24 | L'application fonctionnera sur le port 3000. 25 | 26 | ```bash 27 | npm install 28 | npm start 29 | ``` 30 | 31 | Si vous ne souhaitez pas installer Node.js et que Docker est présent sur votre système, alors utilisez simplement le "Dockerfile" et le script préparera l'application complète dans un conteneur séparé. L'application fonctionnera sur le port 3000. 32 | 33 | ```bash 34 | ./dev.sh 35 | ``` 36 | 37 | ## Contribuant 38 | 39 | Merci pour ton intérêt! Tous les types de contributions sont les bienvenus. **HACK AWAY!** 🔨🔨🔨 40 | 41 | - Forker et cloner ce dépositaire 42 | - Créez votre branche à partir de la branche "maître" 43 | - Exécutez `npm run lint:fix` pour garantir un formatage correct 44 | - Veuillez ouvrir votre RP avec la branche "maître" comme base 45 | 46 | -------------------------------------------------------------------------------- /translations/README-German.md: -------------------------------------------------------------------------------- 1 | # Probleme Zusammenarbeit 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Ein Suchwerkzeug, mit dem Sie Open Source-Projekte finden können 6 | 7 | ## Demo & Verwendung 8 | 9 | - Verwenden Sie die Kippschalter, um die Ergebnisse zu filtern. Geben Sie optional Text-Schlüsselwörter ein 10 | - Klicken Sie auf einen Titel, um das Problem auf GitHub in einem neuen Tab zu öffnen 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Hintergrund 15 | 16 | Die Idee zu diesem Projekt entstand aus dem Wunsch heraus, coole Projekte auf GitHub zu finden, da die native Suche nicht befriedigend genug ist. 17 | 18 | Meine Suche nach Problemen begann während des [Hacktoberfestes](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (eine von Digital Ocean gesponserte jährliche Veranstaltung, die Entwickler ermutigt, sich mit Open Source zu beschäftigen. Machen Sie 4 PRs in einem Monat und erhalten Sie ein KOSTENLOSES T-Shirt 👕) 19 | 20 | ## Lokale Entwicklung 21 | 22 | Um dieses Projekt für die lokale Entwicklung auszuführen, führen Sie die folgenden Schritte in einem Terminal aus, wenn Sie Node.js und NPM installiert haben. Die App läuft auf Port 3000. 23 | 24 | ```bash 25 | npm install 26 | npm start 27 | ``` 28 | 29 | Wenn Sie Node.js nicht installieren möchten und Docker auf Ihrem System vorhanden ist, dann verwenden Sie einfach `Dockerfile` und das Skript, das die gesamte Applikation in einem separaten Container vorbereitet. Die App läuft auf Port 3000. 30 | 31 | ```bash 32 | ./dev.sh 33 | ``` 34 | 35 | ## Mitwirken 36 | 37 | Vielen Dank für Ihr Interesse! Alle Arten von Beiträgen sind willkommen. **HACK AWAY!** 🔨🔨🔨 38 | 39 | - Forken und klonen Sie dieses Repository 40 | - Erstellen Sie Ihren Branch aus dem `master` Branch 41 | - Führen Sie `npm run lint:fix` aus, um die korrekte Formatierung sicherzustellen 42 | - Bitte erstellen Sie Ihre PR mit dem `master` Branch als Basis 43 | -------------------------------------------------------------------------------- /translations/README-Hindi.md: -------------------------------------------------------------------------------- 1 | # इष्षू कोलाब 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > एक खोज उपकरण जिसे आपको ओपन सोर्स प्रोजेक्ट खोजने में मदद करने के लिए डिज़ाइन किया गया है 6 | 7 | ## डेमो और उपयोग 8 | 9 | - परिणामों को फ़िल्टर करने के लिए टॉगल स्विच का उपयोग करें। वैकल्पिक रूप से टेक्स्ट कीवर्ड दर्ज करें 10 | - नए टैब में गिटहब पर समस्या को खोलने के लिए शीर्षक पर क्लिक करें 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## बाक-ग्रौन्ड 15 | 16 | इस परियोजना के लिए विचार गिटहब पर अच्छे परियोजनाओं को खोजने के लिए आता है, लेकिन गिटहब की मूल खोज से संतुष्ट नहीं है। 17 | 18 | मैंने [हैकटॉर्फफेस्ट](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) के दौरान मुद्दों को खोजना शुरू किया। ( डिजिटल ओषन द्वारा प्रायोजित एक वार्षिक कार्यक्रम जो डेवलपर्स को खुले स्रोत के साथ जुड़ने के लिए प्रोत्साहित करता है। एक महीने में 4 पीआर बनाएं और मुफ़्त टी-शर्ट प्राप्त करें 👕). 19 | 20 | ## लोकल डेवलपमेन्ट 21 | 22 | यदि आपके पास Node.js और NPM है तो लोकल डेवलपमेन्ट के लिए इस परियोजना को चलाने के लिए 23 | स्थापित एक टर्मिनल में इन चरणों का पालन करें। ऐप 3000 पोर्ट पर चलेगा। 24 | 25 | ```bash 26 | npm install 27 | npm start 28 | ``` 29 | 30 | यदि आप Node.js को स्थापित नहीं करना चाहते हैं और आपके पास आपके सिस्टम पर डोकर मौजूद है, तो बस `Dockerfile` और उस स्क्रिप्ट का उपयोग करें जो एक अलग कंटेनर में पूरे एप्लिकेशन को तैयार करती है। ऐप 3000 पोर्ट पर चलेगा। 31 | 32 | ```bash 33 | ./dev.sh 34 | ``` 35 | 36 | ## योगदान 37 | 38 | आपकी रूचि के लिए धन्यवाद! सभी प्रकार के योगदान का स्वागत है। **हैक अवे!** 🔨🔨🔨 39 | 40 | - इस रेपोसिटरी को फोर्क और क्लोन करें। 41 | - `मास्टर` शाखा से अपनी शाखा बनाएँ। 42 | - सही स्वरूपण सुनिश्चित करने के लिए `npm run lint:fix` को चलाएं। 43 | - कृपया अपने PR को आधार के रूप में `मास्टर` शाखा के साथ खोलें 44 | 45 | -------------------------------------------------------------------------------- /translations/README-Hungarian.md: -------------------------------------------------------------------------------- 1 | # `Issue` Együttműködés 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Egy keresőeszköz, amelynek célja nyílt forráskódú projektek megtalálása 6 | 7 | ## Bemutató és Használat 8 | 9 | - Használd a csúszkákat az eredmények szűréséhez. Írd be a kulcsszavakat, amikre rá akarsz keresni (opcionális) 10 | - Kattints valamelyik megjelenő címre, hogy megnyisd a probléma (`issue`) GitHub oldalát egy új lapon 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Háttér 15 | 16 | E projekt ötlete abból ered, hogy a GitHub saját keresőfunkciója nem mindig elegendő érdekes projektek megtalálásához. 17 | 18 | Én a [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) 19 | keretében kezdtem keresgélni, ami egy éves esemény a Digital Ocean szponzorálásával. 20 | A rendezvény célja, hogy nyílt forráskódú projektekben való közreműködésre ösztönözze a fejlesztőket. 21 | Hozz létre 4 `pull request`-et a hónap folyamán és egy ingyen pólót kapsz ajándékba.👕 22 | 23 | ## Lokális Fejlesztés 24 | 25 | Amennyiben a Node.js és az NPM már telepítve van, a projekt elindításához futtasd a következő parancsokat a terminálban 26 | (az alkalmazás a 3000-es port-on fog futni): 27 | 28 | ```bash 29 | npm install 30 | npm start 31 | ``` 32 | 33 | Ha nem akarod telepíteni a Node.js-t, de a Docker jelen van a rendszerben, használhatod a Docker fájlt és a lenti szkriptet, 34 | amely külön konténerben készíti elő az alkalmazást és a 3000-es port-on futtatja azt: 35 | 36 | ```bash 37 | ./dev.sh 38 | ``` 39 | 40 | ## Hozzájárulás 41 | 42 | Köszönjük az érdeklődést! Minden típusú hozzájárulást szívesen fogadunk. **Kódolásra fel!** 🔨🔨🔨 43 | 44 | - Készíts egy másolatot a `repo`-ról (`fork` + `clone`) 45 | - Hozz létre egy új ágat (`branch`) a fő ágból (`master branch`) 46 | - `Pull request`-et a master branch-et alapul véve indíts 47 | - Figyeld a `pull request` ellenőrzéseit és győződj meg róla, hogy a Netlify telepítési előnézete megfelelő 48 | 49 | -------------------------------------------------------------------------------- /translations/README-Indonesian.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Sebuah alat yang di desain untuk membantu kamu menemukan projek sumber terbuka 6 | 7 | ## Demo & Penggunaan 8 | 9 | - Gunakan tombon on/off untuk melakukan penyaringan. kamu juga bisa menggunakan kata kunci. 10 | - Klik judul untuk membuka *issue* di GitHub pada tab baru 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Latar Belakang 15 | 16 | Ide dari proyek ini datang dari bagaimana mencari proyek yang keren di GitHub tapi tidak dipersulit dengan pencarian pada GitHub. 17 | 18 | Saya memulai untuk mencari *issue* selama [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) 19 | (Sebuah acara tahunan yang di sponsori oleh Digital Ocean yang menarik pengembang untuk terlibat dalam sumber kode terbuka. Dengan membuat 4 *PRs* dalam sebulan dan mendapatkan BEBAS Kaos 👕). 20 | 21 | ## Pengembangan Lokal 22 | 23 | Menjalankan proyek ini untuk pengembangan lokal, jika kamu sudah menginstall Node.js dan NPM, ikuti langkah - langkah ini di terminal. aplikasi kemudian akan berjalan pada *port* 3000. 24 | 25 | ```bash 26 | npm install 27 | npm start 28 | ``` 29 | 30 | Jika kamu tidak ingin menginstall Node.js dan kamu telah memiliki *Docker* terinstall, cukup gunakan `Dockerfile` dan skrip yang ada akan menyiapkan aplikasi terpisah pada *container*. aplikasi akan berjalan pada *port* 3000. 31 | 32 | ```bash 33 | ./dev.sh 34 | ``` 35 | 36 | ## Berkontribusi 37 | 38 | Terima kasih untuk perhatianmu! Kami menerima semua tipe kontribusi. **HACK AWAY!** 🔨🔨🔨 39 | 40 | - Fork dan clone repository ini. 41 | - Buat branch-mu dari `master` branch. 42 | - Jalankan `npm run lint:fix` untuk melakukan cek format. 43 | - Mohon untuk membuka PR dengan `Master` sebagai branch dasar. -------------------------------------------------------------------------------- /translations/README-Italian.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Un tool di ricerca creato per aiutarti a trovare progetti open source su GitHub 6 | 7 | ## Demo & Utilizzo 8 | 9 | - Usa gli switch per filtrare i risultati. Opzionalmente inserisci parole chiave 10 | - Fai click su di un titolo per aprire la issue su GitHub in una nuova scheda 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Background 15 | 16 | L'idea per questo progetto arriva dal voler trovare bei progetti su GitHub e allo stesso tempo non essere soddisfatti della ricerca nativa di GitHub. 17 | Ho iniziato a cercare delle issue durante [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (un evento annuale sponsorizzato da Digital Ocean che incoraggia gli sviluppatori ad avvicinarsi all'Open Source. Fai 4 Pull request nel mese di Ottobre e ricevi gratis una T-shirt 👕). 18 | 19 | ## Sviluppo in locale 20 | 21 | Per eseguire questo progetto in locale se hai Node.js e NPM installati segui questi step in un terminale, l'app si aprirà sulla portà 3000. 22 | 23 | ```bash 24 | npm install 25 | npm start 26 | ``` 27 | 28 | Se non vuoi installare Node.js ed hai Docker sul tuo sistema, 29 | allora puoi utilizzare il 'Dockerfile' e lo script che prepara l'applicazione in un ambiente separato 30 | L'app si aprirà sulla porta 3000. 31 | 32 | ```bash 33 | ./dev.sh 34 | ``` 35 | 36 | ## Contribuire 37 | 38 | Grazie dell'interesse! Tutti i tipi di contributo sono gratiti. **HACK AWAY!** 🔨🔨🔨 39 | 40 | - Forka e clona questa repository 41 | - Crea il tuo branch dal 'master' branch 42 | - Esegui `npm run lint:fix` per assicurarti del corretto formatting 43 | - Apri una pull request con il `master` branch come base 44 | -------------------------------------------------------------------------------- /translations/README-Japanese: -------------------------------------------------------------------------------- 1 | # Collabを発行する 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > オープンソースプロジェクトを見つけるのに役立つように設計された検索ツール 6 | 7 | ## デモと使用法 8 | 9 | - トグルスイッチを使用して結果をフィルタリングします。 オプションでテキストキーワードを入力します 10 | - タイトルをクリックして、GitHubの新しいタブで問題を開きます 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## バックグラウンド 15 | 16 | このプロジェクトのアイデアは、GitHubでクールなプロジェクトを見つけたいが、GitHubのネイティブ検索に満足していないことから生まれました。 17 | 18 | 私は中に問題を検索し始めました [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (Digital Oceanが主催する毎年恒例のイベントで、開発者がオープンソースに参加することを奨励しています。 月に4つのPRを作成し、無料のTシャツを入手してください 👕). 19 | 20 | ## 地域開発 21 | 22 | Node.jsとNPMがある場合、ローカル開発のためにこのプロジェクトを実行するには 23 | インストールされている端末では、次の手順に従ってください。 アプリはポート3000で実行されます。 24 | 25 | ```bash 26 | npm install 27 | npm start 28 | ``` 29 | 30 | Node.jsをインストールせず、Dockerが存在する場合 31 | システムの場合は、 `Dockerfile`と準備するスクリプトを使用するだけです 32 | アプリケーション全体を別のコンテナに入れます。 アプリはポート3000で実行されます。 33 | 34 | ```bash 35 | ./dev.sh 36 | ``` 37 | 38 | ## 貢献 39 | 40 | ご関心をお寄せいただきありがとうございます! あらゆる種類の貢献を歓迎します。 **ハックアウェイ!** 🔨🔨🔨 41 | 42 | - このリポジトリをフォークしてクローンを作成します 43 | - `master`ブランチからブランチを作成します 44 | - `master`ブランチをベースにしてPRを開いてください 45 | - PRチェックを見て、Netlifyのデプロイプレビューが正しく表示されていることを確認します 46 | 47 | -------------------------------------------------------------------------------- /translations/README-Kannada.md: -------------------------------------------------------------------------------- 1 | # ಇಶು ಕೊಲಾಬ್ 2 | 3 | [! [ನೆಟ್ಲಿಫೈ ಸ್ಥಿತಿ] (https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)] (https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > ಒಂದು ತೆರೆದ ಮೂಲ ಪ್ರಾಜೆಕ್ಟ್ ಅನ್ನು ಹುಡುಕಲು ನಿಮಗೆ ಸಹಾಯ ಮಾಡಲು ವಿನ್ಯಾಸಗೊಳಿಸಲಾದ ಶೋಧ ಸಾಧನ 6 | 7 | ## ಡೆಮೋ & ಬಳಕೆ 8 | 9 | - ಫಲಿತಾಂಶಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಲು ಟಾಗಲ್ ಸ್ವಿಚ್ ಬಳಸಿ. ಐಚ್ಛಿಕವಾಗಿ ಪಠ್ಯ ಕೀಲಿಪದಗಳನ್ನು ನಮೂದಿಸಿ 10 | - ಹೊಸ ಟ್ಯಾಬ್ ನಲ್ಲಿ GitHub ನಲ್ಲಿ ಸಮಸ್ಯೆಯನ್ನು ತೆರೆಯಲು ಶೀರ್ಷಿಕೆಯ ಮೇಲೆ ಕ್ಲಿಕ್ ಮಾಡಿ 11 | 12 | ! [ezgif com-video-to-gif] (https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## ಬಕ್-ಗ್ರೊಂಡ್ 15 | 16 | ಈ ಯೋಜನೆಯ ಕಲ್ಪನೆಯು ಗಿಟ್ ಹಬ್ ನಲ್ಲಿ ಉತ್ತಮ ಯೋಜನೆಗಳನ್ನು ಕಂಡುಹಿಡಿಯಲು ಬರುತ್ತದೆ, ಆದರೆ ಗಿಟ್ ಹಬ್ ನ ಮೂಲ ಆವಿಷ್ಕಾರದಿಂದ ತೃಪ್ತಿಗೊಂಡಿರುವುದಿಲ್ಲ. 17 | 18 | [ಹ್ಯಾಕ್ಟೋಫೆಸ್ಟ್] (https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) ಸಮಯದಲ್ಲಿ ನಾನು ಸಮಸ್ಯೆಗಳನ್ನು ಕಂಡುಹಿಡಿಯಲು ಆರಂಭಿಸಿದೆ. (ಡಿಜಿಟಲ್ ಸಾಗರದಿಂದ ಪ್ರಾಯೋಜಿಸಲ್ಪಟ್ಟ ವಾರ್ಷಿಕ ಕಾರ್ಯಕ್ರಮವು ಮುಕ್ತ ಮೂಲಗಳೊ೦ದಿಗೆ ಸಂಪರ್ಕಿಸಲು ಡೆವಲಪರ್ ಗಳನ್ನು ಪ್ರೋತ್ಸಾಹಿಸುತ್ತದೆ.) ತಿಂಗಳಿಗೆ 4 PR ರಚಿಸಿ ಮತ್ತು ಉಚಿತ ಟೀ ಶರ್ಟ್ ಗಳನ್ನು 👕) ಪಡೆಯಿರಿ. 19 | 20 | ## ಸ್ಥಳೀಯ ಅಭಿವೃದ್ಧಿ 21 | 22 | ನೀವು Node.js ಮತ್ತು NPM ಅನ್ನು ಹೊಂದಿದ್ದರೆ ಸ್ಥಳೀಯ ಅಭಿವೃದ್ಧಿಗಾಗಿ ಈ ಯೋಜನೆಯನ್ನು ಚಾಲನೆ ಮಾಡಲು 23 | ಸ್ಥಾಪಿತವಾದ ಟರ್ಮಿನಲ್ ನಲ್ಲಿ ಈ ಹಂತಗಳನ್ನು ಅನುಸರಿಸಿ. ಈ ಆಪ್ 3000 ಪೋರ್ಟ್ ಗಳಲ್ಲಿ ರನ್ ಆಗುತ್ತದೆ. 24 | 25 | 'ಬಾಷ್' 26 | npm ಸ್ಥಾಪನೆ 27 | npm ಪ್ರಾರಂಭ 28 | ``` 29 | 30 | Node.js ಅನ್ನು ಸ್ಥಾಪಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಮತ್ತು ನಿಮ್ಮ ಸಿಸ್ಟಂನಲ್ಲಿ ಡಾಕರ್ ಅನ್ನು ನೀವು ಹೊಂದಿದ್ದರೆ, ಕೇವಲ 'ಡಾಕರ್ ಫೈಲ್' ಮತ್ತು ಇಡೀ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಪ್ರತ್ಯೇಕ ಕಂಟೇನರ್ ನಲ್ಲಿ ತಯಾರಿಸುವ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಬಳಸಿ. ಈ ಆಪ್ 3000 ಪೋರ್ಟ್ ಗಳಲ್ಲಿ ರನ್ ಆಗುತ್ತದೆ. 31 | 32 | 'ಬಾಷ್' 33 | dev.sh 34 | ``` 35 | 36 | ## ಕೊಡುಗೆಗಳು 37 | 38 | ನಿಮ್ಮ ಆಸಕ್ತಿಗೆ ಧನ್ಯವಾದಗಳು! ಎಲ್ಲಾ ರೀತಿಯ ಕೊಡುಗೆಗಳು ಸ್ವಾಗತಾರ್ಹ. **ಹ್ಯಾಕ್ ಅವೇ!** 🔨🔨🔨 39 | 40 | -ಫೋರ್ಕ್ ಮತ್ತು ಕ್ಲೋನ್ ಈ ರೆಪೊಸಿಟರಿ. 41 | - 'ಮಾಸ್ಟರ್' ಶಾಖೆಯಿಂದ ನಿಮ್ಮ ಶಾಖೆಯನ್ನು ರಚಿಸಿ. 42 | - ಸರಿಯಾದ ಸ್ವರೂಪಣೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು 'npm run lint:fix' ಅನ್ನು ಚಲಾಯಿಸಿ. 43 | - ದಯವಿಟ್ಟು ನಿಮ್ಮ PR ಅನ್ನು ಬೇಸ್ ಆಗಿ 'ಮಾಸ್ಟರ್' ಶಾಖೆಯೊಂದಿಗೆ ತೆರೆಯಿರಿ -------------------------------------------------------------------------------- /translations/README-Malay.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Alat carian yang direka untuk membantu anda mencari projek sumber terbuka 6 | 7 | ## Demo & Penggunaan 8 | 9 | - Gunakan suis togol untuk menapis hasil. Masukkan kata kunci teks secara pilihan 10 | - Klik tajuk untuk membuka 'issue' di GitHub di tab baru 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Latar belakang 15 | 16 | Idea untuk projek ini datang dari keingin mencari projek yang menarik di GitHub tetapi tidak berpuas hati dengan hasil carian asal GitHub. 17 | 18 | Saya mula mencari 'issue' semasa [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (iaitu sebuah acara tahunan yang ditaja oleh Digital Ocean yang mendorong pemaju untuk terlibat dengan sumber terbuka. Buat 4 PR dalam sebulan dan dapatkan T-shirt PERCUMA 👕). 19 | 20 | ## Pembangunan Tempatan 21 | 22 | Untuk menjalankan projek ini dalam pembangunan tempatan, jika anda mempunyai Node.js dan NPM 23 | dipasang ikuti langkah-langkah ini di terminal. Aplikasi ini akan berjalan di port 3000. 24 | 25 | ```bash 26 | npm install 27 | npm start 28 | ``` 29 | 30 | Sekiranya anda tidak mahu memasang Node.js tetapi anda mempunyai Docker pada 31 | sistem, gunakan sahaja `Dockerfile` dan skrip yang menyiapkannya keseluruhan 32 | aplikasi dalam bekas yang berasingan. Aplikasi ini akan berjalan di port 3000. 33 | 34 | ```bash 35 | ./dev.sh 36 | ``` 37 | 38 | ## Cara menyumbang 39 | 40 | Terima kasih kerana minat anda! Semua jenis sumbangan dialu-alukan. **HACK AWAY!** 🔨🔨🔨 41 | 42 | - Fork dan klon repositori ini 43 | - Cipta cabang anda dari cabang `master` 44 | - Sila buka PR anda dengan cabang `master` sebagai pangkalnya 45 | - Lihatlah pemeriksaan PR untuk memastikan pratonton penggunaan Netlify kelihatan betul 46 | 47 | -------------------------------------------------------------------------------- /translations/README-Polish.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Narzędzie do wyszukiwania stworzone, aby pomóc znaleźć Ci projekty open source. 6 | 7 | ## Demo & Sposób używania 8 | 9 | - Możesz użyć przełączników do filtrowania wyników. Opcjonalnie możesz wprowadzić słowa kluczowe. 10 | - Kliknij tytuł, aby otworzyć wątek na GitHubie w nowej karcie. 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Historia projektu 15 | 16 | Pomysł na projekt przyszedł z chęci znalezienia ciekawych projektów na GitHubie, nie bedąc zadowolonym z wbudowanej wyszukiwarki GitHuba. 17 | 18 | Zacząłem szukać wątków podczas [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (coroczne wydarzenie sponsorowane przez Digital Ocean, które zachęca programistów do angażowania się w działania open source. Wykonaj 4 PR-y w ciągu miesiąca i zdobądź DARMOWĄ koszulkę 👕). 19 | 20 | ## Rozbudowa projektu 21 | 22 | Żeby uruchomić ten projekt w celu rozwoju jeśli masz 23 | zainstalowane Node.js i NPM wykonaj te kroki w terminalu. 24 | Aplikacja powinna działać na porcie 3000. 25 | 26 | ```bash 27 | npm install 28 | npm start 29 | ``` 30 | 31 | Jeśli nie chcesz instalować Node.js, a masz Dockera, 32 | użyj `Dockerfile` i skrypt który przygotowuje całą aplikację 33 | w odrębnym kontenerze. Aplikacja powinna działać na porcie 3000. 34 | 35 | ```bash 36 | ./dev.sh 37 | ``` 38 | 39 | ## Wnoszenie własnego wkładu 40 | 41 | Dziekuję za zainteresowanie! Wszystkie okazje przyczyniania się do rozwoju mile widziane. **DZIAŁAJ!** 🔨🔨🔨 42 | 43 | - Użyj przycisku Fork i sklonuj to repozytorium 44 | - Utwórz nową gałąź z gałęzi `master` 45 | - Uruchom `npm run lint:fix` w celu zapewnienia prawidłowego formatowania 46 | - Proszę otwórz swój PR z gałęzią `master` jako baza. 47 | 48 | -------------------------------------------------------------------------------- /translations/README-Portuguese.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Uma ferramenta feita para ajudar você a achar projetos de código aberto 6 | 7 | ## Demo & Uso 8 | 9 | - Use os interruptores para filtrar os resultado. Opcionalmente coloque palavras-chaves 10 | - Clique em um título para abrir uma issue no GitHub em outra aba. 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Por trás 15 | 16 | A ideia para este projeto vem da vontade de achar projetos legais no GitHub mas não estar satisfeito com os resultos nativos do GitHub. 17 | 18 | Eu comecei a procurar por issues na [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (um evento anual oferecido pela Digital Ocean que encoraja desenvolvedores a se envolverem em projetos de código aberto. Faça 4 PRs em um mês e ganhe uma camisa grátis 👕). 19 | 20 | ## Desenvolvimento local 21 | 22 | Para rodar este projeto em um ambiente local, se você tiver Node.js ou NPM instaladdo, 23 | siga os próximos passos em um terminal. A aplicação rodará na porta 3000. 24 | 25 | ```bash 26 | npm install 27 | npm start 28 | ``` 29 | 30 | Se você não quer instalar Node.js e você tem um Docker no seu sistema, 31 | apenas use o `Dockerfile` e o script que prepara toda a aplicação 32 | em um contêiner separado, a aplicação rodará na porta 3000. 33 | 34 | ```bash 35 | ./dev.sh 36 | ``` 37 | 38 | ## Contribuição 39 | 40 | Obrigaddo pelo seu interesse. Todos os tipos de contribuções são bem-vindos. **VAMOS HACKEAR!\*** 🔨🔨🔨 41 | 42 | - Faça um fork e clone deste repositório 43 | - Crie sua branch a partir da branch `master` 44 | - Rode `npm run lint:fix` para garantir a formatação correta 45 | - Por favor, abra seu PR com a branch `master` de referência 46 | -------------------------------------------------------------------------------- /translations/README-Romanian.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | Un instrument de căutare proiectat să te ajute să găsești proiecte open source 6 | 7 | ## Demo & Utilizare 8 | 9 | - Folosește comutatoarele pentru a filtra rezultatele. Opțional, poți introduce cuvinte cheie 10 | - Apasă pe un titlu pentru a deschide un issue în Github într-un tab nou 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Context 15 | 16 | Ideea acestui proiect a venit când voiam să găsesc proiecte cool pe Github, dar nu eram satisfăcut de căutarea nativă din Github. 17 | 18 | Am început să caut issues în timpul [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (un eveniment anual sponsorizat de Digital Ocean care încurajează dezvoltatorii să se implice în proiecte open source. Dacă faci 4 PR-uri într-o lună, primești un tricou GRATIS 👕). 19 | 20 | ## Dezvoltare Locală 21 | 22 | Că să rulezi acest proiect pentru dezvoltare locală, dacă ai NODE.js și NPM instalate, urmează acești pași în terminal. Aplicația va rula pe portul 3000. 23 | 24 | ```bash 25 | npm install 26 | npm start 27 | ``` 28 | 29 | Dacă nu vrei să instalezi Node.js și ai Docker instalat pe sistem, atunci folosește doar `Dockerfile` și scriptul care pregătește toată aplicația într-un container separat. Aplicația va rula pe portul 3000. 30 | 31 | ```bash 32 | ./dev.sh 33 | ``` 34 | 35 | ## Contribuții 36 | 37 | Mulțumim pentru interes! Toate tipurile de contribuții sunt binevenite. **HACK AWAY!** 🔨🔨🔨 38 | 39 | - Creează un fork și o clonă a acestui repository 40 | - Creează un branch din branch-ul `master` 41 | - Rulează `npm run lint:fix` că să te asiguri că formatarea e corectă 42 | - Te rugăm să deschizi PR-ul tău cu branch-ul `master` branch la bază 43 | 44 | -------------------------------------------------------------------------------- /translations/README-Russian.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Инструмент, созданный для поиска open-source проектов 6 | 7 | ## Демо & Использование 8 | 9 | - Используте переключатели для фильтрации результатов. Можно добавить ключевые слова 10 | - Нажмите на заголовок чтобы открыть issue на GitHub в новой вкладке 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Идея 15 | 16 | Идея для этого инструмента возникла после поиска интересных проектов на GitHub. Но так как встроенный поиск не является достаточно удобным, был создан этот проект. 17 | 18 | Я начал искать issues во время [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (это ежегодное событие проспонсированное Digital Ocean. Оно помогает разработчикам поучаствовать в open-source разработке. Сделай 4 PRs и получи БЕСПЛАТНУЮ футболку 👕). 19 | 20 | ## Локальная разработка 21 | 22 | Чтобы запустить этот проект локально, используя Node.js 14 и NPM, следуйте этим шагам в терминале. Приложение запустится на порте 3000. 23 | 24 | ```bash 25 | npm install 26 | npm start 27 | ``` 28 | 29 | Если вы не хотите устанавливать Node.js и у вас есть установленный Docker, тогда просто используйте `Dockerfile` и скрипт который запустит приложение в отдельном контейнере. Приложение запустится на порте 3000. 30 | 31 | ```bash 32 | ./dev.sh 33 | ``` 34 | 35 | ## Участие в проекте 36 | 37 | Спасибо за ваш интерес! Все виды помощи приветствуются. **HACK AWAY!** 🔨🔨🔨 38 | 39 | - Сделайте fork и клонируйте этот репозиторий 40 | - Создайте ветку от `master` ветки 41 | - Выполните `npm run lint:fix` чтобы убедиться, что все форматируется корректно 42 | - Пожалуйста, открывайте PR с `master` веткой в качестве основной 43 | 44 | -------------------------------------------------------------------------------- /translations/README-Spanish.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Una herramienta de búsqueda diseñada para ayudarte a buscar proyectos open source. 6 | 7 | ## Demostración y uso 8 | 9 | - Usa los switch para filtrar resultados. Opcionalmente, añade palabras clave. 10 | - Clica en un título para abrir una issue en GitHub en una pestaña nueva. 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Background 15 | 16 | La idea para este proyecto viene de querer encontrar buenos proyectos en GitHub pero no estar satisfecho con la búsqueda nativa de GitHub. 17 | 18 | Empecé buscando issues durante el [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (un evento anual patrocinado por Digital Ocean para adentrarse en el mundo open source. Crea 4 PR en un mes y llévate una camiseta GRATIS👕). 19 | 20 | ## Desarrollo en local 21 | 22 | Para arrancar este proyecto para desarrollar localmente si dispones de Node.js y NPM instalados, sigue estos pasos en tu terminal. Tu app se ejecutará en el puerto 3000. 23 | 24 | ```bash 25 | npm install 26 | npm start 27 | ``` 28 | 29 | Si no quieres instalar Node.js y tienes Docker en tu sistema, simplemente usa `Dockerfile`y el script que prepara la aplicación en un container por separado. La aplicación se ejecutará en el puerto 3000. 30 | 31 | ```bash 32 | ./dev.sh 33 | ``` 34 | 35 | ## Contribuir 36 | 37 | ¡Gracias por tu interés! Todo tipo de contribuciones son bienvenidas. **A HACKEAR!** 🔨🔨🔨 38 | 39 | - Haz un fork de este repositorio y clónalo. 40 | - Crea tu rama desde la rama `master`. 41 | - Ejecuta `npm run lint:fix` para asegurar un formato correcto. 42 | - Por favor, abre tu PR con la rama `master` como base. 43 | -------------------------------------------------------------------------------- /translations/README-Vietnamese.md: -------------------------------------------------------------------------------- 1 | # Issue Collab 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/a515d6f7-91ed-4ce2-899a-5958d9600ba8/deploy-status)](https://app.netlify.com/sites/issue-collab/deploys) 4 | 5 | > Một công cụ tìm kiếm được thiết kế để giúp bạn tìm những dự án mã nguồn mở 6 | 7 | ## Demo & Cách sử dụng 8 | 9 | - Sử dụng phím bập bênh (toggle) để lọc kết quả. Bạn cũng có thể tùy chọn gõ từ khóa 10 | - Click vào tựa đề để mở một issue trên Github ở tab mới 11 | 12 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/39889198/67807711-ba90b080-fa6b-11e9-9326-c1dface895c2.gif) 13 | 14 | ## Hoàn cảnh 15 | 16 | Ý tưởng cho dự án này đến từ việc mong muốn tìm những dự án hay ho trên Github nhưng vẫn chưa thỏa mãn với tìm kiếm của Github. 17 | 18 | Tôi bắt đầu tìm những issues [Hacktoberfest](https://medium.freecodecamp.org/i-just-got-my-free-hacktoberfest-shirt-heres-a-quick-way-you-can-get-yours-fa78d6e24307) (một sự kiện diễn ra hằng năm được tài trợ bởi Digital Ocean giúp khuyến khích các developer tham gia vào mã nguồn mở. Tạo 4 PRs trong một tháng để nhận được một áo thun MIỄN PHÍ 👕). 19 | 20 | ## Phát triển trên máy 21 | 22 | Để chạy dự án này trên máy (local development) nếu bạn đã cài đặt Node.js hoặc NPM thì thực hiện những bước sau ở terminal. App sẽ chạy tại cổng 3000. 23 | 24 | ```bash 25 | npm installgi 26 | npm start 27 | ``` 28 | 29 | Nếu bạn không muốn cài đặt Node.js và bạn đã có Docker hiện diện trên hệ thống, 30 | thì chỉ cần dùng `Dockerfile` và đoạn script chuẩn bị cho toàn bộ ứng dụng đặt ở một 31 | thư mục chứa khác. App sẽ chạy trên cổng 3000. 32 | 33 | ```bash 34 | ./dev.sh 35 | ``` 36 | 37 | ## Đóng góp 38 | 39 | Cảm ơn vì sự hứng thú của bạn! Tất cả những hình thức đóng góp đều được hoan nghênh. **HACK AWAY!** 🔨🔨🔨 40 | 41 | - Fork và clone từ repository này 42 | - Tạo nhánh mới của bạn từ nhánh `master` 43 | - Hãy mở một PR mới với nhánh `master` là căn bản. 44 | - Đừng quên xem kết quả kiểm tra PR để chắc chắn rằng bản xem trước khi triển khai trên Netlify là chính xác. 45 | 46 | --------------------------------------------------------------------------------