├── .eslintrc ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── new-study-group.md │ └── problem-report.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── assets ├── css │ ├── css │ │ └── fonts │ │ │ ├── Lato-Bold.ttf │ │ │ ├── Lato-Light.ttf │ │ │ └── Lato-Regular.ttf │ ├── grid.css │ └── style.css ├── javascript │ └── main.js └── json │ └── campsitesfinal.json ├── index.html └── package.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "json" 4 | ] 5 | } -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Please read the freeCodeCamp Code of Conduct, which can be found at [Code of Conduct](https://code-of-conduct.freecodecamp.org/) 4 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | The Study Guide Directory is an important tool for helping to bring together campers with their local peers. 4 | 5 | ### Add new and missing groups. 6 | We need help to add new groups as they are created and also to add any that are missing. You can create an issue requesting a new group be added by using the [New Study Group template.](https://github.com/freeCodeCamp/study-group-directory/issues/new?template=new-study-group.md) Alternatively you can use the instructions below to create a pull request to add the entry if you are comfortable doing so. 7 | 8 | ### Fix errors in the directory. 9 | There may also be errors or changes required for the information provided for each group. In particular the location data was sourced from a maps service and sometimes the service identified the wrong location. You can raise an [issue](https://github.com/freeCodeCamp/study-group-directory/issues/new?template=problem-report.md) to let us know of any problems, or you can raise a pull request to fix any mistakes. 10 | 11 | We welcome pull requests from freeCodeCamp campers (our students) and seasoned JavaScript developers alike! Follow these steps to contribute: 12 | 13 | 1. Find an existing issue that needs assistance by searching for the [Help Wanted](https://github.com/freeCodeCamp/study-group-directory/labels/help%20wanted) tag, or [create one](https://github.com/freeCodeCamp/study-group-directory/issues/new?template=problem-report.md) if you've seen an issue not already logged. 14 | 15 | 2. Let us know you are working on it by posting a comment on the issue. 16 | 17 | 3. Create a fork of the repository. 18 | 19 | 4. Create a branch in your fork for your changes. 20 | 21 | 5. When ready submit a pull request to fix, complete the information requested in the template and be sure to include a line in the PR comment that states which issue the PR closes. 22 | 23 | Remember to feel free to ask for help in our [Contributors](https://gitter.im/FreeCodeCamp/Contributors) Gitter room. 24 | 25 | Working on your first Pull Request? You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 26 | 27 | ### The directory data. 28 | The data for the directory is held in the [campsitesfinal.json](https://github.com/freeCodeCamp/study-group-directory/blob/master/assets/json/campsitesfinal.json). The file is large so will be slow to load on GitHub. 29 | 30 | The structure of the file is an array of objects. Each object is an entry in the directory. 31 | 32 | The objects are simply collections of name / value pairs, some are mandatory others optional. 33 | 34 | Sample entry: 35 | ``` javascript 36 | { 37 | "url": "https://www.facebook.com/groups/free.code.camp.to", 38 | "city": "Toronto", 39 | "state": "Ontario", 40 | "country": "Canada", 41 | "coordinates": "43.652921, -79.384901", 42 | "photoUrl": "https://scontent-dft4-2.xx.fbcdn.net/v/t31.0-8/15068500_10210962248150704_3614548903645249833_o.jpg?oh=49670f8c4ac9b83dbbbb1207c3d2b780&oe=599725C0" 43 | } 44 | ``` 45 | 46 | The `url`, `country` and `coordinates` fields are mandatory. `city` and `state` fields should be used to provide name and area of the location of the group. Either may be left blank if the entry still makes sense without it. `photoUrl` can be used to provide the groups chosen photo if it has one - presently this is not used but will be in the Events platform. 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new-study-group.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: New study group 3 | about: Raise a request to add a new study group 4 | 5 | --- 6 | 7 | Please provide the following information to aid in adding your group to the directory: 8 | 9 | ### Esssential 10 | - [ ] Group URL (Web address) 11 | - [ ] Town or City group is located in 12 | - [ ] State / County / Region 13 | - [ ] Country 14 | 15 | ### Nice to have 16 | - [ ] Co-ordinates 17 | 18 | ### If you have one 19 | - [ ] URL of Group Photo 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/problem-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Problem report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | #### Describe your problem and - if possible - how to reproduce it 8 | A clear and concise description of what the problem is. 9 | 10 | #### To Reproduce 11 | Steps to reproduce the behaviour: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | #### What was the expected behaviour 18 | A clear and concise description of what you expected to happen. 19 | 20 | #### If possible, add a screenshot here 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | #### Tell us about your browser and operating system 24 | **Desktop (please complete the following information):** 25 | - OS: [e.g. iOS] 26 | - Browser [e.g. chrome, safari] 27 | - Version [e.g. 22] 28 | 29 | **Smartphone (please complete the following information):** 30 | - Device: [e.g. iPhone6] 31 | - OS: [e.g. iOS8.1] 32 | - Browser [e.g. stock browser, safari] 33 | - Version [e.g. 22] 34 | 35 | #### Additional Information 36 | Add any other information you think will be helpful for us to fix the problem 37 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | #### Pre-Submission Checklist 8 | 9 | 10 | 11 | - [ ] Your pull request targets the `master` branch of freeCodeCamp/study-group-directory. 12 | - [ ] You have only one commit (if not, [squash](http://forum.freecodecamp.org/t/how-to-squash-multiple-commits-into-one-with-git/13231) them into one commit). 13 | 14 | #### Type of Change 15 | 16 | - [ ] Small bug fix (non-breaking change which fixes an issue) 17 | - [ ] New feature (non-breaking change which adds new functionality) 18 | - [ ] Breaking change (fix or feature that would change existing functionality) 19 | - [ ] Update or Correct an existing group entry 20 | - [ ] Add a new group entry 21 | 22 | #### Checklist: 23 | 24 | 25 | - [ ] Tested changes locally. 26 | - [ ] Automated build tests (Travis and Netlify) pass 27 | - [ ] Addressed currently open issue (replace XXXXX with an issue number in next line) 28 | 29 | Closes #XXXXX 30 | 31 | #### Description 32 | 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - '8' 5 | 6 | cache: 7 | directories: 8 | - node_modules 9 | 10 | sudo: false 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2016, Free Code Camp 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # freeCodeCamp Study Group Directory 2 | 3 | This simple website is a catalog of all the freeCodeCamp study groups around the world (that we know about). 4 | 5 | If the user allows location access the groups closest to your browser location are displayed at the top of the page. Alternatively, you can search for groups by place name. 6 | 7 | Find the directory here [freeCodeCamp Study Groups](https://study-group-directory.freecodecamp.org/) 8 | 9 | If you wish to contribute by adding entries, fixing problems or otherwise improving the directory please refer to [CONTRIBUTING.md](https://github.com/freeCodeCamp/study-group-directory/blob/master/.github/CONTRIBUTING.md) 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/css/css/fonts/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freeCodeCamp/study-group-directory/9c94bfb260141ad974bf2f146dadd2a560380860/assets/css/css/fonts/Lato-Bold.ttf -------------------------------------------------------------------------------- /assets/css/css/fonts/Lato-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freeCodeCamp/study-group-directory/9c94bfb260141ad974bf2f146dadd2a560380860/assets/css/css/fonts/Lato-Light.ttf -------------------------------------------------------------------------------- /assets/css/css/fonts/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freeCodeCamp/study-group-directory/9c94bfb260141ad974bf2f146dadd2a560380860/assets/css/css/fonts/Lato-Regular.ttf -------------------------------------------------------------------------------- /assets/css/grid.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V1.0.3 3 | * Copyright 2011, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 7/17/2011 8 | */ 9 | 10 | 11 | div.container { 12 | padding-top: 60px; } 13 | 14 | /* Grid */ 15 | #grid .column, 16 | #grid .columns { 17 | background: #ddd; 18 | height: 25px; 19 | line-height: 25px; 20 | margin-bottom: 10px; 21 | text-align: center; 22 | text-transform: uppercase; 23 | color: #555; 24 | font-size: 12px; 25 | font-weight: bold; 26 | -moz-border-radius: 2px; 27 | -webkit-border-radius: 2px; 28 | border-radius: 2px; } 29 | #grid .column:hover, 30 | #grid .columns:hover { 31 | background: #bbb; 32 | color: #333; } 33 | #grid .example-grid { overflow: hidden; } 34 | 35 | .post-button-note, 36 | .post-button-note a { 37 | font-size: 11px; 38 | color: #999; } 39 | 40 | #examples .four.columns a { 41 | text-decoration: none; 42 | } 43 | #examples .four.columns a:hover { 44 | text-decoration: underline; 45 | } 46 | 47 | 48 | img { 49 | max-width: 100%; 50 | height: auto; } 51 | 52 | .gist-meta { display: none !important;} 53 | 54 | ul ul ul li { margin-bottom: 3px; } 55 | 56 | 57 | /* Mobile */ 58 | @media only screen and (max-width: 767px) { 59 | header h1 { font-size: 34px; line-height: 37px; } 60 | nav { position: relative; } 61 | nav ul, 62 | #examples .four.columns { 63 | padding-top: 30px; 64 | } 65 | } 66 | 67 | /* Non 960 */ 68 | @media only screen and (max-width: 959px) { 69 | nav .button { 70 | padding: 9px 20px 11px; } 71 | } 72 | 73 | /* iPad Portrait/Browser */ 74 | @media only screen and (min-width: 768px) and (max-width: 959px) { 75 | nav { 76 | width: 124px; } 77 | } 78 | 79 | /* Mobile/Browser */ 80 | @media only screen and (max-width: 767px) {} 81 | 82 | /* Mobile Landscape/Browser */ 83 | @media only screen and (min-width: 480px) and (max-width: 767px) {} 84 | 85 | /* Anything smaller than standard 960 */ 86 | @media only screen and (max-width: 959px) {} 87 | 88 | 89 | /* iPad Portrait Only */ 90 | @media only screen and (min-width: 768px) and (max-width: 959px) and (max-device-width: 1000px) {} 91 | 92 | /* Mobile Only */ 93 | @media only screen and (max-width: 767px) and (max-device-width: 1000px) {} 94 | 95 | /* Mobile Landscape Only */ 96 | @media only screen and (min-width: 480px) and (max-width: 767px) and (max-device-width: 1000px) {} 97 | 98 | /* Anything smaller than standard 960 on a device */ 99 | @media only screen and (max-width: 959px) and (max-device-width: 1000px) { 100 | .resize { display: none; } 101 | } 102 | 103 | /* Smaller than standard 960 (devices and browsers) */ 104 | @media only screen and (max-width: 959px) {} 105 | 106 | /* Tablet Portrait size to standard 960 (devices and browsers) */ 107 | @media only screen and (min-width: 768px) and (max-width: 959px) {} 108 | 109 | /* All Mobile Sizes (devices and browser) */ 110 | @media only screen and (max-width: 767px) {} 111 | 112 | /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ 113 | @media only screen and (min-width: 480px) and (max-width: 767px) {} 114 | 115 | /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ 116 | @media only screen and (max-width: 479px) {} 117 | 118 | /* #Base 960 Grid 119 | ================================================== */ 120 | 121 | .container { position: relative; width: 960px; margin: 0 auto; padding: 0; } 122 | .container .column, 123 | .container .columns { float: left; display: inline; margin-left: 10px; margin-right: 10px; } 124 | .row { margin-bottom: 20px; } 125 | 126 | /* Nested Column Classes */ 127 | .column.alpha, .columns.alpha { margin-left: 0; } 128 | .column.omega, .columns.omega { margin-right: 0; } 129 | 130 | /* Base Grid */ 131 | .container .one.column, 132 | .container .one.columns { width: 40px; } 133 | .container .two.columns { width: 100px; } 134 | .container .three.columns { width: 160px; } 135 | .container .four.columns { width: 220px; } 136 | .container .five.columns { width: 280px; } 137 | .container .six.columns { width: 340px; } 138 | .container .seven.columns { width: 400px; } 139 | .container .eight.columns { width: 460px; } 140 | .container .nine.columns { width: 520px; } 141 | .container .ten.columns { width: 580px; } 142 | .container .eleven.columns { width: 640px; } 143 | .container .twelve.columns { width: 700px; } 144 | .container .thirteen.columns { width: 760px; } 145 | .container .fourteen.columns { width: 820px; } 146 | .container .fifteen.columns { width: 880px; } 147 | .container .sixteen.columns { width: 940px; } 148 | 149 | .container .one-third.column { width: 300px; } 150 | .container .two-thirds.column { width: 620px; } 151 | 152 | /* Offsets */ 153 | .container .offset-by-one { padding-left: 60px; } 154 | .container .offset-by-two { padding-left: 120px; } 155 | .container .offset-by-three { padding-left: 180px; } 156 | .container .offset-by-four { padding-left: 240px; } 157 | .container .offset-by-five { padding-left: 300px; } 158 | .container .offset-by-six { padding-left: 360px; } 159 | .container .offset-by-seven { padding-left: 420px; } 160 | .container .offset-by-eight { padding-left: 480px; } 161 | .container .offset-by-nine { padding-left: 540px; } 162 | .container .offset-by-ten { padding-left: 600px; } 163 | .container .offset-by-eleven { padding-left: 660px; } 164 | .container .offset-by-twelve { padding-left: 720px; } 165 | .container .offset-by-thirteen { padding-left: 780px; } 166 | .container .offset-by-fourteen { padding-left: 840px; } 167 | .container .offset-by-fifteen { padding-left: 900px; } 168 | 169 | 170 | 171 | /* #Tablet (Portrait) 172 | ================================================== */ 173 | 174 | /* Note: Design for a width of 768px */ 175 | 176 | @media only screen and (min-width: 768px) and (max-width: 959px) { 177 | .container { width: 768px; } 178 | .container .column, 179 | .container .columns { margin-left: 10px; margin-right: 10px; } 180 | .column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; } 181 | .column.omega, .columns.omega { margin-right: 0; margin-left: 10px; } 182 | .alpha.omega { margin-left: 0; margin-right: 0; } 183 | 184 | .container .one.column, 185 | .container .one.columns { width: 28px; } 186 | .container .two.columns { width: 76px; } 187 | .container .three.columns { width: 124px; } 188 | .container .four.columns { width: 172px; } 189 | .container .five.columns { width: 220px; } 190 | .container .six.columns { width: 268px; } 191 | .container .seven.columns { width: 316px; } 192 | .container .eight.columns { width: 364px; } 193 | .container .nine.columns { width: 412px; } 194 | .container .ten.columns { width: 460px; } 195 | .container .eleven.columns { width: 508px; } 196 | .container .twelve.columns { width: 556px; } 197 | .container .thirteen.columns { width: 604px; } 198 | .container .fourteen.columns { width: 652px; } 199 | .container .fifteen.columns { width: 700px; } 200 | .container .sixteen.columns { width: 748px; } 201 | 202 | .container .one-third.column { width: 236px; } 203 | .container .two-thirds.column { width: 492px; } 204 | 205 | /* Offsets */ 206 | .container .offset-by-one { padding-left: 48px; } 207 | .container .offset-by-two { padding-left: 96px; } 208 | .container .offset-by-three { padding-left: 144px; } 209 | .container .offset-by-four { padding-left: 192px; } 210 | .container .offset-by-five { padding-left: 240px; } 211 | .container .offset-by-six { padding-left: 288px; } 212 | .container .offset-by-seven { padding-left: 336px; } 213 | .container .offset-by-eight { padding-left: 384px; } 214 | .container .offset-by-nine { padding-left: 432px; } 215 | .container .offset-by-ten { padding-left: 480px; } 216 | .container .offset-by-eleven { padding-left: 528px; } 217 | .container .offset-by-twelve { padding-left: 576px; } 218 | .container .offset-by-thirteen { padding-left: 624px; } 219 | .container .offset-by-fourteen { padding-left: 672px; } 220 | .container .offset-by-fifteen { padding-left: 720px; } 221 | } 222 | 223 | 224 | /* #Mobile (Portrait) 225 | ================================================== */ 226 | 227 | /* Note: Design for a width of 320px */ 228 | 229 | @media only screen and (max-width: 767px) { 230 | .container { width: 300px; } 231 | .container .columns, 232 | .container .column { margin: 0; } 233 | 234 | .container .one.column, 235 | .container .one.columns, 236 | .container .two.columns, 237 | .container .three.columns, 238 | .container .four.columns, 239 | .container .five.columns, 240 | .container .six.columns, 241 | .container .seven.columns, 242 | .container .eight.columns, 243 | .container .nine.columns, 244 | .container .ten.columns, 245 | .container .eleven.columns, 246 | .container .twelve.columns, 247 | .container .thirteen.columns, 248 | .container .fourteen.columns, 249 | .container .fifteen.columns, 250 | .container .sixteen.columns, 251 | .container .one-third.column, 252 | .container .two-thirds.column { width: 300px; } 253 | 254 | /* Offsets */ 255 | .container .offset-by-one, 256 | .container .offset-by-two, 257 | .container .offset-by-three, 258 | .container .offset-by-four, 259 | .container .offset-by-five, 260 | .container .offset-by-six, 261 | .container .offset-by-seven, 262 | .container .offset-by-eight, 263 | .container .offset-by-nine, 264 | .container .offset-by-ten, 265 | .container .offset-by-eleven, 266 | .container .offset-by-twelve, 267 | .container .offset-by-thirteen, 268 | .container .offset-by-fourteen, 269 | .container .offset-by-fifteen { padding-left: 0; } 270 | 271 | } 272 | 273 | 274 | /* #Mobile (Landscape) 275 | ================================================== */ 276 | 277 | /* Note: Design for a width of 480px */ 278 | 279 | @media only screen and (min-width: 480px) and (max-width: 767px) { 280 | .container { width: 420px; } 281 | .container .columns, 282 | .container .column { margin: 0; } 283 | 284 | .container .one.column, 285 | .container .one.columns, 286 | .container .two.columns, 287 | .container .three.columns, 288 | .container .four.columns, 289 | .container .five.columns, 290 | .container .six.columns, 291 | .container .seven.columns, 292 | .container .eight.columns, 293 | .container .nine.columns, 294 | .container .ten.columns, 295 | .container .eleven.columns, 296 | .container .twelve.columns, 297 | .container .thirteen.columns, 298 | .container .fourteen.columns, 299 | .container .fifteen.columns, 300 | .container .sixteen.columns, 301 | .container .one-third.column, 302 | .container .two-thirds.column { width: 420px; } 303 | } 304 | 305 | 306 | /* #Clearing 307 | ================================================== */ 308 | 309 | /* Self Clearing Goodness */ 310 | .container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; } 311 | 312 | /* Use clearfix class on parent to clear nested columns, 313 | or wrap each row of columns in a
*/ 314 | .clearfix:before, 315 | .clearfix:after, 316 | .row:before, 317 | .row:after { 318 | content: '\0020'; 319 | display: block; 320 | overflow: hidden; 321 | visibility: hidden; 322 | width: 0; 323 | height: 0; } 324 | .row:after, 325 | .clearfix:after { 326 | clear: both; } 327 | .row, 328 | .clearfix { 329 | zoom: 1; } 330 | 331 | /* You can also use a
to clear columns */ 332 | .clear { 333 | clear: both; 334 | display: block; 335 | overflow: hidden; 336 | visibility: hidden; 337 | width: 0; 338 | height: 0; 339 | } 340 | 341 | /* Forms 342 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 343 | input[type="email"], 344 | input[type="number"], 345 | input[type="search"], 346 | input[type="text"], 347 | input[type="tel"], 348 | input[type="url"], 349 | input[type="password"], 350 | textarea, 351 | select { 352 | padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ 353 | background-color: #fff; 354 | border: 1px solid #D1D1D1; 355 | border-radius: 4px; 356 | box-shadow: none; 357 | box-sizing: border-box; } 358 | /* Removes awkward default styles on some inputs for iOS */ 359 | input[type="email"], 360 | input[type="number"], 361 | input[type="search"], 362 | input[type="text"], 363 | input[type="tel"], 364 | input[type="url"], 365 | input[type="password"], 366 | textarea { 367 | -webkit-appearance: none; 368 | -moz-appearance: none; 369 | appearance: none; } 370 | textarea { 371 | min-height: 65px; 372 | padding-top: 6px; 373 | padding-bottom: 6px; } 374 | input[type="email"]:focus, 375 | input[type="number"]:focus, 376 | input[type="search"]:focus, 377 | input[type="text"]:focus, 378 | input[type="tel"]:focus, 379 | input[type="url"]:focus, 380 | input[type="password"]:focus, 381 | textarea:focus, 382 | select:focus { 383 | border: 1px solid #006400; 384 | outline: 0; } 385 | label, 386 | legend { 387 | display: block; 388 | margin-bottom: .5rem; 389 | font-weight: 600; } 390 | fieldset { 391 | padding: 0; 392 | border-width: 0; } 393 | input[type="checkbox"], 394 | input[type="radio"] { 395 | display: inline; } 396 | label > .label-body { 397 | display: inline-block; 398 | margin-left: .5rem; 399 | font-weight: normal; } 400 | 401 | -------------------------------------------------------------------------------- /assets/css/style.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, output, ruby, section, summary, time, mark, audio, video { 4 | margin: 0; 5 | padding: 0; 6 | border: 0; 7 | vertical-align: baseline; } 8 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, section { 9 | display: block; } 10 | } 11 | 12 | h1, h2, h3, h4, h5, h6 { 13 | color: #222; 14 | } 15 | 16 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; } 17 | h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;} 18 | h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; } 19 | h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; } 20 | h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; } 21 | h5 { font-size: 17px; line-height: 24px; } 22 | h6 { font-size: 14px; line-height: 21px; } 23 | 24 | #camps a, #camp a:visited { color: #006400; outline: 0; } 25 | #camp a:hover, a:focus { color: #000; } 26 | p a, p a:visited { line-height: inherit; } 27 | 28 | #closeCamps a, #closeCamps a:visited { color: #006400; outline: 0; } 29 | #closeCamps a:hover, a:focus { color: #000; } 30 | 31 | p{ 32 | color: #222222; 33 | font-size: 20px; 34 | font-weight: 300; 35 | margin: 0 0 20px 0; 36 | } 37 | 38 | body { 39 | font-family: 'Lato', sans-serif; 40 | } 41 | 42 | p img { margin: 0; } 43 | 44 | 45 | .palette-pad { 46 | min-height: 70px; 47 | font-size: inherit; 48 | } 49 | 50 | 51 | .small{ 52 | font-size: 16px; 53 | } 54 | 55 | header{ 56 | color: #FFFFFF; 57 | height: 500px; 58 | width: 100%; 59 | position: relative; 60 | background: linear-gradient(#006400, #006400); 61 | background-image: linear-gradient(rgb(0, 100, 0), rgb(3, 95, 29)); 62 | background-position-x: initial; 63 | background-position-y: initial; 64 | background-size: initial; 65 | background-repeat-x: initial; 66 | background-repeat-y: initial; 67 | background-attachment: initial; 68 | background-origin: initial; 69 | background-clip: initial; 70 | background-color: initial; 71 | } 72 | 73 | .center{ 74 | text-align: center; 75 | } 76 | 77 | header{ 78 | margin-bottom: 75px; 79 | } 80 | 81 | .navbar { 82 | position: fixed; 83 | width: 100%; 84 | height: 50px; 85 | background: #006400; 86 | color: #fff; 87 | z-index: 1; 88 | } 89 | .navbar-brand { 90 | float: left; 91 | margin-top: 5px; 92 | margin-left: 20px; 93 | line-height: 20px; 94 | } 95 | 96 | .navbar-brand img{ 97 | height: 40px; 98 | width: 270px; 99 | } 100 | .navbar-right { 101 | float: right; 102 | font-size: 18px; 103 | margin-right: 15px; 104 | margin-top: 10px; 105 | } 106 | 107 | @media(max-width: 640px){ 108 | .navbar-brand { 109 | margin-top: 5px; 110 | margin-left: 0; 111 | } 112 | .navbar-right { 113 | float: right; 114 | margin: 0 5px; 115 | margin-top: -15px; 116 | 117 | } 118 | nav { 119 | display: inline-block; 120 | } 121 | } 122 | 123 | 124 | nav ul li a { 125 | color: #fff; 126 | text-decoration: none; 127 | font-size: 20px; 128 | } 129 | @media(max-width: 640px){ 130 | nav ul li a { 131 | font-size: 16px; 132 | 133 | } 134 | } 135 | 136 | nav ul { 137 | 138 | list-style: none; 139 | 140 | } 141 | 142 | 143 | .pad{ 144 | padding-bottom: 75px; 145 | } 146 | 147 | .center{ 148 | text-align: center; 149 | } 150 | 151 | .logo-border{ 152 | border: 1px solid #D7E0E0; 153 | border-radius: 4px; 154 | padding: 75px; 155 | } 156 | 157 | .logo-border-glyph{ 158 | border: 1px solid #D7E0E0; 159 | border-radius: 4px; 160 | padding: 60px; 161 | } 162 | 163 | .logo-border-small{ 164 | border: 1px solid #D7E0E0; 165 | border-radius: 4px; 166 | padding: 40px; 167 | } 168 | 169 | .misuse-border{ 170 | border: 1px solid #D7E0E0; 171 | border-radius: 4px; 172 | padding: 10px; 173 | } 174 | 175 | .color-palette{ 176 | height: 160px; 177 | width: 160px; 178 | border-radius: 100px; 179 | } 180 | 181 | /*Free Code Camp Colors*/ 182 | 183 | .dark-green{ 184 | background-color: #006400; 185 | } 186 | 187 | .green{ 188 | background-color: #007E00; 189 | } 190 | 191 | .yellow{ 192 | background-color: #FFEE18; 193 | } 194 | 195 | .orange{ 196 | background-color: #FF9C2A; 197 | } 198 | 199 | .light-orange{ 200 | background-color: #FFAD25; 201 | } 202 | 203 | .blue{ 204 | background-color: #3949AB; 205 | } 206 | 207 | .light-blue{ 208 | background-color: #2DB9FF; 209 | } 210 | 211 | .red{ 212 | background-color: #FF4025; 213 | } 214 | 215 | .light-red{ 216 | background-color: #FF6D58; 217 | } 218 | 219 | .pink{ 220 | background-color: #F06292; 221 | } 222 | 223 | .purple{ 224 | background-color: #BA68C8; 225 | } 226 | 227 | .brown{ 228 | background-color: #A4755F; 229 | } 230 | 231 | .grey{ 232 | background-color: #E0E0E0; 233 | } 234 | 235 | .dark-grey{ 236 | background-color: #939393; 237 | } 238 | 239 | .black{ 240 | background-color: #2A2A2A; 241 | } 242 | 243 | .white{ 244 | background-color: #FFFFFF; 245 | border: 1px solid #D7E0E0; 246 | } 247 | 248 | // Youtube responsive div code 249 | .intrinsic-container { 250 | position: relative; 251 | height: 0; 252 | overflow: hidden; 253 | padding-bottom: 56.25%; 254 | } 255 | 256 | .intrinsic-container iframe { 257 | position: absolute; 258 | top:0; 259 | left: 0; 260 | width: 100%; 261 | height: 100%; 262 | } 263 | 264 | .twitter-blue { 265 | color: #0084b4 266 | } 267 | 268 | /*176 220 264 330*/ 269 | 270 | .profile-image { 271 | border-radius: 0%; 272 | height: 264px; 273 | width: 330px; 274 | } 275 | 276 | .big-break { 277 | margin-top: 50px; 278 | } 279 | 280 | .stick { 281 | position: fixed; 282 | top: 50px; 283 | } 284 | 285 | .align-right { 286 | text-align: right; 287 | } 288 | 289 | #camps, #closeCamps { 290 | list-style: none; 291 | } 292 | input { 293 | margin: 10px 0; 294 | 295 | } 296 | 297 | #camps > li > div > img { 298 | display: none; 299 | } 300 | 301 | #closecamps > li > div > img { 302 | display: inline; 303 | } 304 | 305 | .loader { 306 | margin: 0 auto; 307 | border: 25px solid #f3f3f3; /* Light grey */ 308 | border-top: 25px solid #006400; /* Dark green */ 309 | border-radius: 50%; 310 | width: 75px; 311 | height: 75px; 312 | animation: spin 2s linear infinite; 313 | display: none; 314 | } 315 | 316 | @keyframes spin { 317 | 0% { transform: rotate(0deg); } 318 | 100% { transform: rotate(360deg); } 319 | } 320 | 321 | a { 322 | color: #006400; 323 | a:hover, a:focus { 324 | color: #000; 325 | } 326 | } 327 | 328 | .big-search-field { 329 | font-size: 32px; 330 | width: 100% 331 | } 332 | 333 | #search-nearby { 334 | display: none; 335 | } 336 | 337 | #select-search-nearby { 338 | /*border: 0; 339 | -webkit-appearance: none;*/ 340 | color: #222; 341 | font-size: 28px; 342 | font-weight: bold; 343 | height: auto; 344 | width: auto; 345 | } 346 | -------------------------------------------------------------------------------- /assets/javascript/main.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | 3 | $('form').on('submit', function(e) { e.preventDefault(); }); 4 | 5 | $('.hidden-code').click(function(e) { 6 | e.preventDefault(); 7 | $(this).children('.gist').slideToggle(); 8 | }); 9 | 10 | var originalText; 11 | $('.example-grid').children().hover( 12 | function() { 13 | originalText = $(this).text(); 14 | $(this).html($(this).width()+'px'); 15 | }, 16 | function() { 17 | $(this).html(originalText); 18 | } 19 | ); 20 | 21 | $('#select-search-nearby').change(function(e){ 22 | e.preventDefault(); 23 | $('#closeCamps').children().hide(); 24 | $('#closeCamps>div').filter(function(){ 25 | return parseInt($('h4>a>div', this)[0].innerText.match(/(\d+.\d\d)\skm/)[1]) < parseInt($('#select-search-nearby').val()); 26 | }).show(); 27 | }); 28 | 29 | searchNearby(100); 30 | 31 | // find close to coordinates 32 | function searchNearby(maxRadius) { 33 | if (navigator.geolocation) { 34 | navigator.geolocation.getCurrentPosition(function(position){ 35 | NearestCities(position.coords.latitude, position.coords.longitude, maxRadius); 36 | }); 37 | } else { 38 | // loc = "Geolocation is not supported by this browser."; 39 | NearestCities(38.8951, -77.0367, maxRadius); 40 | } 41 | } 42 | 43 | // Convert Degress to Radians 44 | function Deg2Rad(deg) { 45 | return deg * Math.PI / 180; 46 | } 47 | 48 | function PythagorasEquirectangular(lat1, lon1, lat2, lon2) { 49 | lat1 = Deg2Rad(lat1); 50 | lat2 = Deg2Rad(lat2); 51 | lon1 = Deg2Rad(lon1); 52 | lon2 = Deg2Rad(lon2); 53 | var R = 6371; // km 54 | var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2); 55 | var y = (lat2 - lat1); 56 | var d = Math.sqrt(x * x + y * y) * R; 57 | return d; 58 | } 59 | 60 | var cities = []; 61 | var cityNames = []; 62 | 63 | $.getJSON('assets/json/campsitesfinal.json').then(function(data) { 64 | data.forEach(function(loc) { 65 | const coordString = loc.coordinates; 66 | let values = coordString.split(","); 67 | 68 | var lat = ConvertDMSToDD(parseFloat(values[0])); 69 | var lng = ConvertDMSToDD(parseFloat(values[1])); 70 | let coords = [loc.city, loc.state, loc.country, lat, lng]; 71 | 72 | cities.push(coords); 73 | 74 | cityNames.push( 75 | (loc.city.length > 0 ? loc.city + ", " : "") + 76 | (loc.state.length > 0 ? loc.state + ", " : "") + 77 | loc.country 78 | ); 79 | 80 | 81 | }); 82 | }); 83 | 84 | function ConvertDMSToDD(degrees) { 85 | var dd = degrees; 86 | 87 | // if (direction == "S" || direction == "W") { 88 | // dd = dd * -1; 89 | // } // Don't do anything for N or E 90 | return dd; 91 | } 92 | 93 | function NearestCities(latitude, longitude, maxRadius) { 94 | var closest = []; 95 | 96 | for (index = 0; index < cities.length; ++index) { 97 | var dif = PythagorasEquirectangular(latitude, longitude, cities[index][3], cities[index][4]); 98 | if (dif < maxRadius) { 99 | closest.push({index:index, dist:dif}); 100 | } 101 | } 102 | 103 | closest = closest.sort(function(a, b){ 104 | return a.dist - b.dist; 105 | }); 106 | 107 | $.getJSON('assets/json/campsitesfinal.json').then(function(data) { 108 | $('#search-nearby').show(); 109 | for (let i = 0; i < closest.length; i++){ 110 | let loc = data[closest[i].index]; 111 | let img = loc.photoUrl || "https://s3.amazonaws.com/freecodecamp/bannercropped.png", 112 | city = loc.city, 113 | state = loc.state, 114 | country = loc.country, 115 | url = loc.url, 116 | coords = loc.coordinates; 117 | let location = ''; 118 | 119 | location = (city.length > 0 ? city + ", " : "") + 120 | (state.length > 0 ? state + ", " : "") + 121 | country; 122 | 123 | $("#closeCamps").append( 124 | ` 125 |
126 |

127 | 128 | No Image 129 |
130 | ${location} - ${closest[i].dist.toFixed(2)} km 131 | (${((closest[i].dist.toFixed(2))*0.621371).toFixed(2)} mi) 132 |
133 |
134 |

135 |
136 | ` 137 | ); 138 | } 139 | }); 140 | } 141 | 142 | //full list of locations 143 | $.getJSON('assets/json/campsitesfinal.json').then(function(data) { 144 | 145 | data.forEach(function(loc) { 146 | const img = loc.photoUrl || "https://s3.amazonaws.com/freecodecamp/bannercropped.png", 147 | city = loc.city, 148 | state = loc.state, 149 | country = loc.country, 150 | url = loc.url; 151 | let location = ''; 152 | 153 | location = (city.length > 0 ? city + ", " : "") + 154 | (state.length > 0 ? state + ", " : "") + 155 | country; 156 | 157 | $("#camps").append( 158 | ` 159 |
  • 160 |
    161 |

    162 | 163 | ${location} 164 | 165 |

    166 |
    167 |
  • 168 | ` 169 | ); 170 | 171 | }); 172 | }); 173 | var typing_timer; 174 | //search 175 | $('#search').on('keyup', function () { 176 | var li = []; 177 | var valThis = this.value.toLowerCase(); 178 | valThis = valThis.toLowerCase(); 179 | valThis = valThis.replace(/\s+/g, ''); 180 | 181 | var searchFunc = function(){ 182 | $('.city').each(function() { 183 | var currentLiText = $(this).text(), 184 | showCurrentLi = ((currentLiText.toLowerCase()).replace(/\s+/g, '')).indexOf(valThis) !== -1; 185 | $(this).parent().parent().toggle(showCurrentLi); 186 | 187 | if(showCurrentLi==true){ 188 | li.push(showCurrentLi); 189 | 190 | } 191 | setTimeout(function(){ 192 | $('.loader').hide(); 193 | }, 250); 194 | }); 195 | var size = $('#camps').find('li').length; 196 | $("#res").html(li.length); 197 | } 198 | 199 | 200 | clearTimeout(this.typing_timer); 201 | 202 | this.typing_timer = setTimeout(searchFunc, 250) 203 | $('.loader').show(); 204 | 205 | 206 | 207 | }); 208 | 209 | 210 | // responsive 16x9 iframe - restricted by parent's width 211 | var resizeIframe = function() { 212 | $('.responsive-iframe iframe').each(function(index, iframe) { 213 | var parentWidth = $(iframe).parent().width(); 214 | $(iframe).width(parentWidth); 215 | $(iframe).height(parentWidth / 16 * 9); 216 | }); 217 | }; 218 | $(window).on('resize', resizeIframe); 219 | resizeIframe(); 220 | }); 221 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Find a local freeCodeCamp study group in your city and code together with other developers in person 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 83 | 95 |
    96 | 97 |
    98 |
    99 |
    100 |
    101 |

    Join a nearby freeCodeCamp study group.

    102 |

    Code together with other people in your city.

    103 |
    104 |
    105 |

    Join the study group closest to you or search for a place name below.

    106 |
    107 |

    Note: Currently most freeCodeCamp Study Groups are using Facebook Groups to organize themselves. We are building our own events platform to use in the future. If you can't find a study group near you, you can create one.

    108 |
    109 |
    110 |
    111 |
    112 |
    113 |

    Study groups within 114 | 119 |

    120 |
    121 |
    122 |
    123 | 124 |
    125 |
    126 |
    127 | 128 |
    129 |
    130 |
    131 | 132 |
    133 |
    134 |
    135 |
    136 | 137 |
    138 |

    139 | If you cannot find the exact place name you are looking for try searching for nearby places, or the the region or even country the place is in. 140 |

    141 |

    142 | Results: 143 |

    144 |
    145 |
    146 |
      147 |
    148 |
    149 |
    150 |
    151 |
    152 |
    153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "study-groups-fcc", 3 | "version": "0.0.1", 4 | "description": "freeCodeCamp study group directory static page", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"No tests\"", 8 | "pretest": "npm run lint", 9 | "lint": "eslint . --ext .json" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/freeCodeCamp/study-group-directory.git" 14 | }, 15 | "author": "", 16 | "license": "BSD-3-Clause", 17 | "bugs": { 18 | "url": "https://github.com/freeCodeCamp/study-group-directory/issues" 19 | }, 20 | "homepage": "https://github.com/freeCodeCamp/study-group-directory#readme", 21 | "devDependencies": { 22 | "eslint": "^3.18.0", 23 | "eslint-plugin-json": "^1.2.0" 24 | } 25 | } 26 | --------------------------------------------------------------------------------