├── .dockerignore ├── .drone.yml ├── .editorconfig ├── .env.sample ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── images │ └── logo.svg └── workflows │ └── schedule-milestones.yaml ├── .gitignore ├── .prettierrc ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── assets ├── fonts │ ├── IBMPlexMono-Bold.woff2 │ ├── IBMPlexMono-ExtraLight.woff2 │ ├── IBMPlexMono-Light.woff2 │ ├── IBMPlexMono-Medium.woff2 │ ├── IBMPlexMono-Regular.woff2 │ ├── IBMPlexMono-SemiBold.woff2 │ ├── IBMPlexMono-Text.woff2 │ ├── IBMPlexMono-Thin.woff2 │ ├── IBMPlexSansArabic-Bold.woff2 │ ├── IBMPlexSansArabic-ExtraLight.woff2 │ ├── IBMPlexSansArabic-Light.woff2 │ ├── IBMPlexSansArabic-Medium.woff2 │ ├── IBMPlexSansArabic-Regular.woff2 │ ├── IBMPlexSansArabic-SemiBold.woff2 │ ├── IBMPlexSansArabic-Text.woff2 │ └── IBMPlexSansArabic-Thin.woff2 └── images │ ├── filter │ └── icon-small-chevron.svg │ ├── footer │ ├── icon-github.svg │ ├── icon-small-cc.svg │ ├── icon-small-coded.svg │ ├── icon-small-fb.svg │ ├── icon-small-github.svg │ ├── icon-small-josa.svg │ ├── icon-small-love.svg │ └── icon-small-twitter.svg │ ├── hero │ └── jordan-commits.svg │ ├── methodology │ └── algorithm.png │ ├── navbar │ ├── bars-solid.svg │ ├── logo.svg │ └── x-circle.svg │ └── stats │ ├── icon-commits.svg │ ├── icon-organization.svg │ ├── icon-users.svg │ └── josa-icon.svg ├── components ├── AreaChart.vue ├── BarChart.vue ├── Card.vue ├── ChartsPeriodDropdown.vue ├── CheckBox.vue ├── Contributors.vue ├── FilterSection.vue ├── Hero.vue ├── HomePageHero.vue ├── InputsSection.vue ├── LastUpdated.vue ├── MobileMenuButton.vue ├── MobileMenuItems.vue ├── OrganizationCard.vue ├── Organizations.vue ├── OrganizationsFilter.vue ├── OrganizationsInput.vue ├── PaginationBar.vue ├── PeriodDropdown.vue ├── QAndA.vue ├── RadioButton.vue ├── SearchInput.vue ├── Stats.vue ├── TheFooter.vue ├── TheHeader.vue ├── TopDevelopers.vue ├── TopOrganizations.vue └── UserCard.vue ├── docker-compose.yaml ├── jsconfig.json ├── layouts ├── default.vue └── global.css ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages ├── contributors │ └── index.vue ├── index.vue ├── methodology │ └── index.vue └── organizations │ └── index.vue ├── plugins └── vue-apexchart.js ├── static └── favicon.png ├── store └── index.js ├── tailwind.config.js └── utils └── debounce.js /.dockerignore: -------------------------------------------------------------------------------- 1 | # Git 2 | .git 3 | .gitignore 4 | .gitattributes 5 | .github 6 | 7 | # Docker 8 | Dockerfile 9 | docker-compose.yaml 10 | docker-compose.yml 11 | .dockerignore 12 | 13 | # Documentation 14 | *.md 15 | LICENSE 16 | 17 | # macOS (optional) 18 | .DS_Store 19 | 20 | # Visual Studio Code (optional) 21 | .vscode 22 | 23 | # Drone 24 | .drone.yml 25 | 26 | .env 27 | .env.* 28 | 29 | # editot configs 30 | .eslintrc.* 31 | .prettierrc 32 | -------------------------------------------------------------------------------- /.drone.yml: -------------------------------------------------------------------------------- 1 | # Drone CI File! 2 | 3 | kind: pipeline 4 | type: kubernetes 5 | name: default 6 | 7 | metadata: 8 | namespace: builds 9 | 10 | node_selector: 11 | doks.digitalocean.com/node-pool: josa-cloud-np 12 | 13 | steps: 14 | - name: build 15 | image: plugins/docker 16 | settings: 17 | repo: josaorg/contributions-web 18 | build_args: 19 | [ 20 | CONTRIBUTIONS_API_URL=http://contributions.api.svc.cluster.local, 21 | MATOMO_SITE_ID=10, 22 | TARGET_ENV=production 23 | ] 24 | build_args_from_env: 25 | [ 26 | DRONE_BUILD_NUMBER, 27 | DRONE_BUILD_LINK, 28 | DRONE_COMMIT_SHA, 29 | DRONE_COMMIT_LINK, 30 | DRONE_REPO_LINK, 31 | DRONE_BUILD_FINISHED, 32 | ] 33 | tags: 34 | - ${DRONE_COMMIT_SHA} 35 | - stable 36 | username: 37 | from_secret: docker_username 38 | password: 39 | from_secret: docker_password 40 | - name: notify 41 | image: plugins/slack 42 | settings: 43 | webhook: 44 | from_secret: slack_webhook 45 | channel: heartbeat 46 | depends_on: 47 | - build 48 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | # endpoint for API 2 | CONTRIBUTIONS_API_URL= 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true, 6 | }, 7 | parserOptions: { 8 | parser: '@babel/eslint-parser', 9 | requireConfigFile: false, 10 | }, 11 | extends: ['@nuxtjs', 'plugin:nuxt/recommended', 'prettier'], 12 | plugins: [], 13 | // add your custom rules here 14 | rules: {}, 15 | } 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/schedule-milestones.yaml: -------------------------------------------------------------------------------- 1 | name: schedule-milestones 2 | 3 | on: 4 | schedule: 5 | - cron: 0 0 * * SUN # Run every Sunday at midnight 6 | 7 | jobs: 8 | generate: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | 13 | - name: Schedule Milestones 14 | uses: readmeio/scheduled-milestones@v1.1.1 15 | id: scheduled 16 | with: 17 | token: ${{ secrets.GITHUB_TOKEN }} 18 | title: 'S-' 19 | days: Thursday 20 | count: 4 21 | format: YYYY-MM-DD 22 | 23 | - name: Created Milestones 24 | run: echo ${{ steps.scheduled.outputs.milestones }} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.* 78 | !.env.sample 79 | 80 | # parcel-bundler cache (https://parceljs.org/) 81 | .cache 82 | .parcel-cache 83 | 84 | # Next.js build output 85 | .next 86 | out 87 | 88 | # Nuxt.js build / generate output 89 | .nuxt 90 | .output 91 | dist 92 | 93 | # Gatsby files 94 | .cache/ 95 | # Comment in the public line in if your project uses Gatsby and not Next.js 96 | # https://nextjs.org/blog/next-9-1#public-directory-support 97 | # public 98 | 99 | # vuepress build output 100 | .vuepress/dist 101 | 102 | # vuepress v2.x temp and cache directory 103 | .temp 104 | .cache 105 | 106 | # Docusaurus cache and generated files 107 | .docusaurus 108 | 109 | # Serverless directories 110 | .serverless/ 111 | 112 | # FuseBox cache 113 | .fusebox/ 114 | 115 | # DynamoDB Local files 116 | .dynamodb/ 117 | 118 | # TernJS port file 119 | .tern-port 120 | 121 | # Stores VSCode versions used for testing VSCode extensions 122 | .vscode-test 123 | .vscode 124 | .vscode/* 125 | 126 | # yarn v2 127 | .yarn/cache 128 | .yarn/unplugged 129 | .yarn/build-state.yml 130 | .yarn/install-state.gz 131 | .pnp.* 132 | 133 | # IDEs and editors 134 | /.idea 135 | .project 136 | .classpath 137 | .c9/ 138 | *.launch 139 | .settings/ 140 | *.sublime-workspace 141 | 142 | # Other 143 | assets/data 144 | **.adminjs 145 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to Contributions Web 2 | 3 | Thank you for your interest in contributing to our project! We welcome your help and appreciate your support. 4 | To ensure a smooth and collaborative process, please take a moment to review this contributing guide. 5 | 6 | ## Code or Documentation Contributions 7 | 8 | 1. [Fork this repository](https://github.com/jordanopensource/contributions-web/fork). 9 | 2. Clone the forked repository to your local machine with this command: 10 | `git clone https://github.com//contributions-web.git` 11 | 3. Switch to `development` branch with this command: `git checkout development`. 12 | **If your contribution is a documentation, jump to step 7 below**. 13 | 4. (**_You can ignore this step if you're using docker compose_**) Create a `.env` file and copy the content of [`.env.sample`](https://github.com/jordanopensource/contributions-web/blob/development/.env.sample) file into it, 14 | then add the value(s) of environment variable(s). 15 | You can use the current running API URL as the value to `CONTRIBUTIONS_API_URL` variable as the following: 16 | `CONTRIBUTIONS_API_URL=https://contributions.api.prod.josa.ngo/` 17 | 18 | 5. [Run the project locally](https://github.com/jordanopensource/contributions-web/blob/main/CONTRIBUTING.md#running-the-project-locally). 19 | 6. Check current [issues](https://github.com/jordanopensource/contributions-web/issues?q=is%3Aopen+is%3Aissue+label%3Ahacktoberfest), 20 | and if you're a beginner, you can [filter issues with `good first issues` label](https://github.com/jordanopensource/contributions-web/issues?q=is%3Aopen+is%3Aissue+label%3Ahacktoberfest+label%3A%22good+first+issue%22). 21 | If you decide to work on one of the issue, write a comment on the issue asking to be assigned to it. 22 | _Do not work on issues that you're not assigned to in order to avoid duplicate work_. 23 | 7. Create a new branch from `development` branch for the task that you want to work on: 24 | `git checkout -b /branch-title` 25 | - ``: The prefix should be one of the following: 26 | - `feat` for new features 27 | - `fix` for bug fixes 28 | - `task` for other general tasks 29 | - `docs` for documentation 30 | - `branch-title` should be short and concise and written in kebab-case (separate each word with '-') 31 | **Example**: 32 | ```sh 33 | git checkout development && git pull # pull the latest changes from development branch 34 | 35 | git checkout -b fix/type # create new branch 36 | ``` 37 | 38 | 8. Write descriptive and concise commit messages 39 | Follow these guidelines when writing commit messages: 40 | - Limit the first line of the commit message to 72 characters or less. 41 | - Use the imperative mood and present tense in the subject line, e.g. "Fix typo in the homepage" instead of "Fixed typo...". 42 | - Use the body of the commit message to provide additional context or details, _if necessary_. 43 | - Use bullet points in the body of the commit message to break down changes, _if necessary_. 44 | 45 | 9. Push to your branch and then make a pull request from your branch to the base `development`. 46 | 47 | ### Running the Project Locally 48 | 49 | #### Using Docker 50 | Make sure that [docker](https://docs.docker.com/engine/install/) is installed on your system 51 | and then run the project locally using [docker compose](https://github.com/jordanopensource/contributions-web/blob/development/docker-compose.yaml) with this command: 52 | `docker compose up`. 53 | 54 | #### Using Node: 55 | 1. Make sure [Node](https://nodejs.org/en) v16 is installed. Alternatively, you can use [NVM](https://github.com/nvm-sh/nvm#installing-and-updating) to install any node version. 56 | 2. Navigate to the project directory and run `npm i` to install the dependancies. 57 | 3. Run the project in development mode by running `npm run dev`. You can now preview the project on port 3000 by visiting http://localhost:3000/ in your browser. 58 | 59 | ## Issues and Features Requests 60 | 61 | If you want to report a bug or submit a feature request, please use one of the [templates here](https://github.com/jordanopensource/contributions-web/issues/new/choose). 62 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG CONTRIBUTIONS_API_URL=https://contributions.api.dev.josa.ngo HOST=0.0.0.0 PORT=3000 USER=node MATOMO_SITE_ID=11 TARGET_ENV DRONE_COMMIT_SHA=${DRONE_COMMIT_SHA} DRONE_BUILD_NUMBER=${DRONE_BUILD_NUMBER} DRONE_BUILD_LINK=${DRONE_BUILD_LINK} DRONE_COMMIT_LINK=${DRONE_COMMIT_LINK} DRONE_REPO_LINK=${DRONE_REPO_LINK} DRONE_BUILD_FINISHED=${DRONE_BUILD_FINISHED} DEBUG='false' 2 | 3 | ########### 4 | # BUILDER # 5 | ########### 6 | FROM node:16-alpine3.14 as builder 7 | 8 | ARG CONTRIBUTIONS_API_URL 9 | ARG HOST 10 | ARG PORT 11 | ARG MATOMO_SITE_ID 12 | ARG TARGET_ENV 13 | ARG DRONE_COMMIT_SHA 14 | ARG DRONE_BUILD_NUMBER 15 | ARG DRONE_BUILD_LINK 16 | ARG DRONE_COMMIT_LINK 17 | ARG DRONE_REPO_LINK 18 | ARG DRONE_BUILD_FINISHED 19 | ARG DEBUG 20 | 21 | # copy build context and install dependencies 22 | WORKDIR /workspace 23 | COPY . . 24 | RUN npm install 25 | 26 | # Inject the enviromental variables 27 | ENV CONTRIBUTIONS_API_URL=$CONTRIBUTIONS_API_URL HOST=$HOST PORT=$PORT MATOMO_SITE_ID=$MATOMO_SITE_ID TARGET_ENV=${TARGET_ENV} DRONE_COMMIT_SHA=$DRONE_COMMIT_SHA DRONE_BUILD_NUMBER=${DRONE_BUILD_NUMBER} DRONE_BUILD_LINK=${DRONE_BUILD_LINK} DRONE_COMMIT_LINK=${DRONE_COMMIT_LINK} DRONE_REPO_LINK=${DRONE_REPO_LINK} DRONE_BUILD_FINISHED=${DRONE_BUILD_FINISHED} DEBUG=${DEBUG} 28 | 29 | # build NuxtJS project 30 | RUN npm run build:modern 31 | 32 | ########### 33 | # PROJECT # 34 | ########### 35 | FROM node:16-slim 36 | 37 | ARG CONTRIBUTIONS_API_URL 38 | ARG HOST 39 | ARG PORT 40 | ARG USER 41 | ARG MATOMO_SITE_ID 42 | ARG TARGET_ENV 43 | ARG DRONE_COMMIT_SHA 44 | ARG DRONE_BUILD_NUMBER 45 | ARG DRONE_BUILD_LINK 46 | ARG DRONE_COMMIT_LINK 47 | ARG DRONE_REPO_LINK 48 | ARG DRONE_BUILD_FINISHED 49 | ARG DEBUG 50 | 51 | # copy builder output to project workdir 52 | WORKDIR /app 53 | COPY --from=builder --chown=${USER}:${USER} /workspace/.nuxt /app/.nuxt 54 | COPY --from=builder --chown=${USER}:${USER} /workspace/nuxt.config.js /app/nuxt.config.js 55 | COPY --from=builder --chown=${USER}:${USER} /workspace/node_modules /app/node_modules 56 | COPY --from=builder --chown=${USER}:${USER} /workspace/package.json /app/ 57 | 58 | # Inject the enviromental variables 59 | ENV CONTRIBUTIONS_API_URL=$CONTRIBUTIONS_API_URL HOST=$HOST PORT=$PORT MATOMO_SITE_ID=$MATOMO_SITE_ID TARGET_ENV=${TARGET_ENV} DRONE_COMMIT_SHA=$DRONE_COMMIT_SHA DRONE_BUILD_NUMBER=${DRONE_BUILD_NUMBER} DRONE_BUILD_LINK=${DRONE_BUILD_LINK} DRONE_COMMIT_LINK=${DRONE_COMMIT_LINK} DRONE_REPO_LINK=${DRONE_REPO_LINK} DRONE_BUILD_FINISHED=${DRONE_BUILD_FINISHED} DEBUG=${DEBUG} 60 | 61 | # set user context 62 | USER ${USER} 63 | 64 | # expose port 65 | EXPOSE ${PORT} 66 | 67 | # run for production 68 | CMD [ "npm", "run", "start:modern"] 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 | 5 | Logo 6 | 7 | 8 |

top-contributors-web

9 |

10 | The web client for the Jordan Top Contributors website. 11 |
12 | Explore the docs » 13 |
14 |
15 | 16 | · 17 | Report Bug 18 | · 19 | Request Feature 20 |

21 |

22 | 23 |
24 |

Table of Contents

25 |
    26 |
  1. 27 | About The Project 28 | 31 |
  2. 32 |
  3. 33 | Getting Started 34 | 39 |
  4. 40 |
  5. Usage
  6. 41 |
  7. Roadmap
  8. 42 |
  9. Contributing
  10. 43 |
  11. License
  12. 44 |
  13. Contact
  14. 45 |
  15. Acknowledgements
  16. 46 |
47 |
48 | 49 | 50 | 51 | ## About The Project 52 | 53 | This is a Nuxtjs web client for the Jordan Top Contributors Website, a website that displays the top contributors to open source repositories in Jordan. 54 | 55 | ### Built With 56 | 57 | - [Nuxt.js](https://nuxtjs.org) 58 | - [Tailwind CSS](https://tailwindcss.com/) 59 | 60 | 61 | 62 | ## Getting Started 63 | 64 | To get a local copy up and running follow these simple steps. 65 | 66 | ### Prerequisites 67 | 68 | 1. Download and install the latest version of Node.js from [here](https://nodejs.org/en/download/). 69 | 70 | ### Installation 71 | 72 | 1. Clone the repo 73 | ```sh 74 | git clone https://github.com/jordanopensource/top-contributors-web.git 75 | ``` 76 | 2. Install NPM packages 77 | ```sh 78 | npm install 79 | ``` 80 | 81 | ### Running 82 | 83 | #### Development 84 | 85 | To run the project locally for development purposes: 86 | 87 | 1. Run the project 88 | 89 | ```sh 90 | $ npm run dev 91 | ``` 92 | 93 | 2. Go to `http://localhost:3000` 94 | 95 | #### Production 96 | 97 | To build and run the project locally for production purposes: 98 | 99 | 1. Build the project 100 | 101 | ```sh 102 | $ npm run build 103 | ``` 104 | 105 | 2. Launch the production server 106 | 107 | ```sh 108 | $ npm run start 109 | ``` 110 | 111 | 112 | 113 | ## Roadmap 114 | 115 | See the [open issues](https://github.com/jordanopensource/top-contributors-web/issues) for a list of proposed features (and known issues). 116 | 117 | 118 | 119 | ## Contributing 120 | 121 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. 122 | 123 | 1. Fork the Project 124 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 125 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 126 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 127 | 5. Open a Pull Request 128 | 129 | 130 | 131 | ## License 132 | 133 | Distributed under the Apache License. See `LICENSE` for more information. 134 | 135 | 136 | 137 | ## Contact 138 | 139 | Jordan Open Source Association - [@jo_osa](https://twitter.com/@jo_osa) - info@josa.ngo 140 | 141 | Project Link: [https://github.com/jordanopensource/top-contributors-web](https://github.com/jordanopensource/top-contributors-web) 142 | -------------------------------------------------------------------------------- /assets/fonts/IBMPlexMono-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexMono-Bold.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexMono-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexMono-ExtraLight.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexMono-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexMono-Light.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexMono-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexMono-Medium.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexMono-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexMono-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexMono-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexMono-SemiBold.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexMono-Text.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexMono-Text.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexMono-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexMono-Thin.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexSansArabic-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexSansArabic-Bold.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexSansArabic-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexSansArabic-ExtraLight.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexSansArabic-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexSansArabic-Light.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexSansArabic-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexSansArabic-Medium.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexSansArabic-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexSansArabic-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexSansArabic-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexSansArabic-SemiBold.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexSansArabic-Text.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexSansArabic-Text.woff2 -------------------------------------------------------------------------------- /assets/fonts/IBMPlexSansArabic-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/fonts/IBMPlexSansArabic-Thin.woff2 -------------------------------------------------------------------------------- /assets/images/filter/icon-small-chevron.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/images/footer/icon-github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 39 | 41 | 46 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /assets/images/footer/icon-small-cc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /assets/images/footer/icon-small-coded.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/images/footer/icon-small-fb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /assets/images/footer/icon-small-github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /assets/images/footer/icon-small-josa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 20 | 22 | 26 | 29 | 34 | 38 | 42 | 46 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /assets/images/footer/icon-small-love.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/images/footer/icon-small-twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /assets/images/hero/jordan-commits.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/methodology/algorithm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/assets/images/methodology/algorithm.png -------------------------------------------------------------------------------- /assets/images/navbar/bars-solid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/navbar/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 20 | 27 | 31 | 34 | 39 | 43 | 47 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /assets/images/navbar/x-circle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/stats/icon-commits.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/images/stats/icon-organization.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/images/stats/icon-users.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/images/stats/josa-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 39 | 41 | 46 | 53 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /components/AreaChart.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | 26 | 64 | -------------------------------------------------------------------------------- /components/BarChart.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | 26 | 48 | -------------------------------------------------------------------------------- /components/Card.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 32 | 33 | 65 | -------------------------------------------------------------------------------- /components/ChartsPeriodDropdown.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 82 | 83 | 104 | -------------------------------------------------------------------------------- /components/CheckBox.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 42 | 43 | 99 | -------------------------------------------------------------------------------- /components/Contributors.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 77 | 78 | 105 | -------------------------------------------------------------------------------- /components/FilterSection.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 50 | 51 | 94 | -------------------------------------------------------------------------------- /components/Hero.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | 26 | 48 | -------------------------------------------------------------------------------- /components/HomePageHero.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 35 | 36 | 67 | -------------------------------------------------------------------------------- /components/InputsSection.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 199 | 200 | 240 | -------------------------------------------------------------------------------- /components/LastUpdated.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 31 | 32 | 37 | -------------------------------------------------------------------------------- /components/MobileMenuButton.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 33 | -------------------------------------------------------------------------------- /components/MobileMenuItems.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 25 | 26 | 47 | -------------------------------------------------------------------------------- /components/OrganizationCard.vue: -------------------------------------------------------------------------------- 1 | 52 | 53 | 68 | 69 | 136 | -------------------------------------------------------------------------------- /components/Organizations.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 72 | 73 | 100 | -------------------------------------------------------------------------------- /components/OrganizationsFilter.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 50 | 51 | 94 | -------------------------------------------------------------------------------- /components/OrganizationsInput.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 100 | 101 | 110 | -------------------------------------------------------------------------------- /components/PaginationBar.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 77 | 78 | 126 | -------------------------------------------------------------------------------- /components/PeriodDropdown.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 130 | 131 | 148 | -------------------------------------------------------------------------------- /components/QAndA.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 49 | 50 | 70 | -------------------------------------------------------------------------------- /components/RadioButton.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 64 | 65 | 121 | -------------------------------------------------------------------------------- /components/SearchInput.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 49 | 50 | 56 | -------------------------------------------------------------------------------- /components/Stats.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 65 | 66 | 85 | -------------------------------------------------------------------------------- /components/TheFooter.vue: -------------------------------------------------------------------------------- 1 | 94 | 95 | 100 | 101 | 114 | -------------------------------------------------------------------------------- /components/TheHeader.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 58 | 59 | 90 | -------------------------------------------------------------------------------- /components/TopDevelopers.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 38 | 39 | 56 | -------------------------------------------------------------------------------- /components/TopOrganizations.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 41 | 42 | 59 | -------------------------------------------------------------------------------- /components/UserCard.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 83 | 84 | 151 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | frontend: 3 | build: 4 | context: . 5 | image: contributions-web 6 | container_name: contributions-web 7 | restart: unless-stopped 8 | environment: 9 | CONTRIBUTIONS_API_URL: http://contributions-api:8080 10 | PORT: 3000 11 | HOST: contributions-web 12 | networks: 13 | - contributions-network 14 | ports: 15 | - "3000:3000" 16 | 17 | backend: 18 | build: 19 | context: ../contributions-api 20 | image: contributions-api 21 | container_name: contributions-api 22 | restart: unless-stopped 23 | environment: 24 | DB_URL: mongodb://mongodb:27017/top-contributors 25 | PORT: 8080 26 | HOST: contributions-api 27 | networks: 28 | - contributions-network 29 | ports: 30 | - "8080:8080" 31 | 32 | mongodb: 33 | image: mongo 34 | container_name: mongodb 35 | restart: unless-stopped 36 | environment: 37 | MONGO_INITDB_DATABASE: top-contributors 38 | networks: 39 | - contributions-network 40 | ports: 41 | - "27017:27017" 42 | 43 | networks: 44 | contributions-network: 45 | driver: bridge 46 | 47 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "~/*": ["./*"], 6 | "@/*": ["./*"], 7 | "~~/*": ["./*"], 8 | "@@/*": ["./*"] 9 | } 10 | }, 11 | "exclude": ["node_modules", ".nuxt", "dist"] 12 | } 13 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /layouts/global.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'IBM Sans'; 3 | font-style: normal; 4 | font-weight: 100; 5 | font-display: swap; 6 | src: local('IBM Sans'), 7 | url(~assets/fonts/IBMPlexSansArabic-Thin.woff2) format('trueType'); 8 | } 9 | 10 | @font-face { 11 | font-family: 'IBM Sans'; 12 | font-style: normal; 13 | font-weight: 200; 14 | font-display: swap; 15 | src: local('IBM Sans'), 16 | url(~assets/fonts/IBMPlexSansArabic-ExtraLight.woff2) format('trueType'); 17 | } 18 | 19 | @font-face { 20 | font-family: 'IBM Sans'; 21 | font-style: normal; 22 | font-weight: 300; 23 | font-display: swap; 24 | src: local('IBM Sans'), 25 | url(~assets/fonts/IBMPlexSansArabic-Light.woff2) format('trueType'); 26 | } 27 | 28 | @font-face { 29 | font-family: 'IBM Sans'; 30 | font-style: normal; 31 | font-weight: 400; 32 | font-display: swap; 33 | src: local('IBM Sans'), 34 | url(~assets/fonts/IBMPlexSansArabic-Regular.woff2) format('trueType'); 35 | } 36 | 37 | @font-face { 38 | font-family: 'IBM Sans'; 39 | font-style: normal; 40 | font-weight: 500; 41 | font-display: swap; 42 | src: local('IBM Sans'), 43 | url(~assets/fonts/IBMPlexSansArabic-Medium.woff2) format('trueType'); 44 | } 45 | 46 | @font-face { 47 | font-family: 'IBM Sans'; 48 | font-style: normal; 49 | font-weight: 600; 50 | font-display: swap; 51 | src: local('IBM Sans'), 52 | url(~assets/fonts/IBMPlexSansArabic-SemiBold.woff2) format('trueType'); 53 | } 54 | 55 | @font-face { 56 | font-family: 'IBM Sans'; 57 | font-style: normal; 58 | font-weight: 700; 59 | font-display: swap; 60 | src: local('IBM Sans'), 61 | url(~assets/fonts/IBMPlexSansArabic-Bold.woff2) format('trueType'); 62 | } 63 | 64 | @font-face { 65 | font-family: 'IBM Mono'; 66 | font-style: normal; 67 | font-weight: 100; 68 | font-display: swap; 69 | src: local('IBM Mono'), 70 | url(~assets/fonts/IBMPlexMono-Thin.woff2) format('trueType'); 71 | } 72 | 73 | @font-face { 74 | font-family: 'IBM Mono'; 75 | font-style: normal; 76 | font-weight: 200; 77 | font-display: swap; 78 | src: local('IBM Mono'), 79 | url(~assets/fonts/IBMPlexMono-ExtraLight.woff2) format('trueType'); 80 | } 81 | 82 | @font-face { 83 | font-family: 'IBM Mono'; 84 | font-style: normal; 85 | font-weight: 300; 86 | font-display: swap; 87 | src: local('IBM Mono'), 88 | url(~assets/fonts/IBMPlexMono-Light.woff2) format('trueType'); 89 | } 90 | 91 | @font-face { 92 | font-family: 'IBM Mono'; 93 | font-style: normal; 94 | font-weight: 400; 95 | font-display: swap; 96 | src: local('IBM Mono'), 97 | url(~assets/fonts/IBMPlexMono-Regular.woff2) format('trueType'); 98 | } 99 | 100 | @font-face { 101 | font-family: 'IBM Mono'; 102 | font-style: normal; 103 | font-weight: 500; 104 | font-display: swap; 105 | src: local('IBM Mono'), 106 | url(~assets/fonts/IBMPlexMono-Medium.woff2) format('trueType'); 107 | } 108 | 109 | @font-face { 110 | font-family: 'IBM Mono'; 111 | font-style: normal; 112 | font-weight: 600; 113 | font-display: swap; 114 | src: local('IBM Mono'), 115 | url(~assets/fonts/IBMPlexMono-SemiBold.woff2) format('trueType'); 116 | } 117 | 118 | @font-face { 119 | font-family: 'IBM Mono'; 120 | font-style: normal; 121 | font-weight: 700; 122 | font-display: swap; 123 | src: local('IBM Mono'), 124 | url(~assets/fonts/IBMPlexMono-Bold.woff2) format('trueType'); 125 | } 126 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // Global page headers: https://go.nuxtjs.dev/config-head 3 | head: { 4 | title: 'Jordan’s Top Contributors', 5 | meta: [ 6 | { charset: 'utf-8' }, 7 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 8 | { 9 | hid: 'description', 10 | name: 'description', 11 | content: 12 | 'See Jordan’s top Open Source contributors and find out where you rank among your fellow Jordanian developers, are you in the top 10?', 13 | }, 14 | { name: 'format-detection', content: 'telephone=no' }, 15 | ], 16 | link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.png' }], 17 | }, 18 | 19 | server: { 20 | host: process.env.HOST, // default: localhost 21 | port: process.env.PORT, // default: 3000 22 | }, 23 | 24 | // Global CSS: https://go.nuxtjs.dev/config-css 25 | css: ['~layouts/global.css'], 26 | 27 | // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins 28 | plugins: [{ src: '~/plugins/vue-apexchart.js', ssr: false }], 29 | 30 | // Auto import components: https://go.nuxtjs.dev/config-components 31 | components: true, 32 | 33 | // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules 34 | buildModules: [ 35 | // https://go.nuxtjs.dev/eslint 36 | '@nuxtjs/eslint-module', 37 | '@nuxtjs/tailwindcss', 38 | ], 39 | 40 | // Modules: https://go.nuxtjs.dev/config-modules 41 | modules: [ 42 | '@josango/nuxt-build-banner', 43 | [ 44 | 'nuxt-matomo', 45 | { matomoUrl: '//track.josa.ngo/', siteId: process.env.MATOMO_SITE_ID }, 46 | ], 47 | // https://go.nuxtjs.dev/axios 48 | '@nuxtjs/axios', 49 | // https://go.nuxtjs.dev/pwa 50 | '@nuxtjs/pwa', 51 | '@nuxtjs/proxy', 52 | 'nuxt-healthcheck', 53 | ], 54 | 55 | // Axios module configuration: https://go.nuxtjs.dev/config-axios 56 | axios: { 57 | proxy: true, 58 | }, 59 | 60 | proxy: { 61 | '/v1': { target: process.env.CONTRIBUTIONS_API_URL }, 62 | }, 63 | 64 | publicRuntimeConfig: { 65 | CONTRIBUTIONS_API_URL: process.env.CONTRIBUTIONS_API_URL, 66 | siteID: process.env.MATOMO_SITE_ID, 67 | buildCommitSHA: process.env.DRONE_COMMIT_SHA, 68 | DRONE_COMMIT_SHA: process.env.DRONE_COMMIT_SHA, 69 | DRONE_COMMIT_LINK: process.env.DRONE_COMMIT_LINK, 70 | DRONE_BUILD_NUMBER: process.env.DRONE_BUILD_NUMBER, 71 | DRONE_BUILD_LINK: process.env.DRONE_BUILD_LINK, 72 | DRONE_REPO_LINK: process.env.DRONE_REPO_LINK, 73 | DRONE_BUILD_FINISHED: process.env.DRONE_BUILD_FINISHED, 74 | TARGET_ENV: process.env.TARGET_ENV 75 | }, 76 | 77 | healthcheck: { 78 | path: '/healthcheck', 79 | contentType: 'application/json', 80 | healthy: () => { 81 | return JSON.stringify({ result: 'yeeeeeeeeeeees' }) 82 | }, 83 | }, 84 | 85 | // PWA module configuration: https://go.nuxtjs.dev/pwa 86 | pwa: { 87 | manifest: { 88 | lang: 'en', 89 | }, 90 | }, 91 | 92 | // Build Configuration: https://go.nuxtjs.dev/config-build 93 | build: {}, 94 | } 95 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "top-contributors", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "nuxt", 7 | "build:modern": "nuxt build --modern=server", 8 | "start:modern": "nuxt start --modern=server", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", 13 | "lint": "npm run lint:js" 14 | }, 15 | "dependencies": { 16 | "@josango/nuxt-build-banner": "^1.0.2", 17 | "@nuxtjs/axios": "^5.13.6", 18 | "@nuxtjs/proxy": "^2.1.0", 19 | "@nuxtjs/pwa": "^3.3.5", 20 | "apexcharts": "^3.45.1", 21 | "core-js": "^3.35.0", 22 | "nuxt": "^2.17.2", 23 | "nuxt-healthcheck": "^1.0.1", 24 | "nuxt-matomo": "^1.2.4", 25 | "vue-apexcharts": "^1.6.2", 26 | "vue-lazy-hydration": "^2.0.0-beta.4" 27 | }, 28 | "devDependencies": { 29 | "@babel/eslint-parser": "^7.22.15", 30 | "@nuxtjs/eslint-config": "^10.0.0", 31 | "@nuxtjs/eslint-module": "^3.0.2", 32 | "@nuxtjs/tailwindcss": "^5.3.5", 33 | "eslint": "^8.49.0", 34 | "eslint-config-prettier": "^9.0.0", 35 | "eslint-plugin-nuxt": "^4.0.0", 36 | "eslint-plugin-promise": "^6.1.1", 37 | "eslint-plugin-vue": "^9.17.0", 38 | "postcss": "^8.4.33", 39 | "prettier": "^3.0.3" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pages/contributors/index.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 579 | 580 | 615 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 35 | -------------------------------------------------------------------------------- /pages/methodology/index.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 106 | 107 | 127 | -------------------------------------------------------------------------------- /pages/organizations/index.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 302 | 303 | 327 | -------------------------------------------------------------------------------- /plugins/vue-apexchart.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueApexCharts from 'vue-apexcharts' 3 | 4 | Vue.component('Apexchart', VueApexCharts) 5 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanopensource/contributions-web/420a3de68169e86074119a7d17c1803e76782300/static/favicon.png -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | export const state = () => ({ 2 | orgsCount: 0, 3 | usersCount: 0, 4 | contributionsLastMonth: 0, 5 | users: [], 6 | orgs: [], 7 | pageCount: 0, 8 | currentPage: 1, 9 | sortBy: 'score', 10 | orgs_sortBy: 'repos_stars', 11 | period: 'last_30_days', 12 | chartPeriod: 'last_year', 13 | show: 'all', 14 | countType: 'all', 15 | orgSearchTerm: '', 16 | userSearchTerm: '', 17 | }) 18 | 19 | export const getters = { 20 | getPageCount: (state) => state.pageCount, 21 | getCurrentPage: (state) => state.currentPage, 22 | getSortBy: (state) => state.sortBy, 23 | getOrgsSortBy: (state) => state.orgs_sortBy, 24 | getPeriod: (state) => state.period, 25 | getChartPeriod: (state) => state.chartPeriod, 26 | getShow: (state) => state.show, 27 | getCountType: (state) => state.countType, 28 | getOrgSearchTerm: (state) => state.orgSearchTerm, 29 | getUserSearchTerm: (state) => state.userSearchTerm, 30 | } 31 | 32 | export const mutations = { 33 | setOrgsCount(state, orgsCount) { 34 | state.orgsCount = orgsCount 35 | }, 36 | setUsers(state, users) { 37 | state.users = users 38 | }, 39 | setOrgs(state, orgs) { 40 | state.orgs = orgs 41 | }, 42 | setUsersCount(state, usersCount) { 43 | state.usersCount = usersCount 44 | }, 45 | setContributionsLastMonth(state, contributionsLastMonth) { 46 | state.contributionsLastMonth = contributionsLastMonth 47 | }, 48 | setPageCount(state, pageCount) { 49 | state.pageCount = pageCount 50 | }, 51 | setCurrentPage(state, currentPage) { 52 | state.currentPage = currentPage 53 | }, 54 | setSortBy(state, sortBy) { 55 | state.sortBy = sortBy 56 | }, 57 | setOrgsSortBy(state, sortBy) { 58 | state.orgs_sortBy = sortBy 59 | }, 60 | setPeriod(state, period) { 61 | state.period = period 62 | }, 63 | setChartPeriod(state, chartPeriod) { 64 | state.chartPeriod = chartPeriod 65 | }, 66 | setShow(state, show) { 67 | state.show = show 68 | }, 69 | setCountType(state, countType) { 70 | state.countType = countType 71 | }, 72 | setOrgSearchTerm(state, searchTerm) { 73 | state.orgSearchTerm = searchTerm 74 | }, 75 | setUserSearchTerm(state, searchTerm) { 76 | state.userSearchTerm = searchTerm 77 | }, 78 | } 79 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: [ 3 | './components/**/*.{vue,js}', 4 | './layouts/**/*.vue', 5 | './pages/**/*.vue', 6 | './plugins/**/*.{js,ts}', 7 | './nuxt.config.{js,ts}', 8 | ], 9 | theme: { 10 | extend: { 11 | height: { 12 | 720: '45rem', 13 | }, 14 | colors: { 15 | gray: { 16 | DEFAULT: '#edeeef', 17 | }, 18 | lightgrey: { 19 | DEFAULT: '#f4f4f5', 20 | }, 21 | }, 22 | }, 23 | }, 24 | variants: { 25 | extend: {}, 26 | }, 27 | plugins: [], 28 | } 29 | -------------------------------------------------------------------------------- /utils/debounce.js: -------------------------------------------------------------------------------- 1 | export function debounce(fn, wait) { 2 | let timer 3 | return function (...args) { 4 | if (timer) { 5 | clearTimeout(timer) // clear any pre-existing timer 6 | } 7 | const context = this // get the current context 8 | timer = setTimeout(() => { 9 | fn.apply(context, args) // call the function if time expires 10 | }, wait) 11 | } 12 | } 13 | --------------------------------------------------------------------------------