Browse Source

Added semi-functional administration pages

development
Godwin 8 years ago
parent
commit
b719b2c8ef
  1. BIN
      app/assets/images/logo-original.png
  2. 317
      app/assets/images/logo-original.svg
  3. 2407
      app/assets/images/logo.ai
  4. BIN
      app/assets/images/runes.jpg
  5. 19
      app/assets/javascripts/editor.js
  6. 82
      app/assets/javascripts/housing.js
  7. 119
      app/assets/javascripts/main.js
  8. 585
      app/assets/stylesheets/_application.scss
  9. 12
      app/assets/stylesheets/user-mailer.scss
  10. 39
      app/controllers/application_controller.rb
  11. 306
      app/controllers/conferences_controller.rb
  12. 273
      app/helpers/application_helper.rb
  13. 2
      app/models/conference.rb
  14. 3
      app/models/event.rb
  15. 23
      app/models/event_location.rb
  16. 13
      app/models/user.rb
  17. 8
      app/models/workshop.rb
  18. 2
      app/views/application/_header.html.haml
  19. 4
      app/views/application/locale_not_available.html.haml
  20. 7
      app/views/conferences/_administration.html.haml
  21. 2
      app/views/conferences/_contact_info.html.haml
  22. 11
      app/views/conferences/_hosting.html.haml
  23. 19
      app/views/conferences/admin/_broadcast.html.haml
  24. 1
      app/views/conferences/admin/_broadcast_sent.html.haml
  25. 7
      app/views/conferences/admin/_edit.html.haml
  26. 36
      app/views/conferences/admin/_events.html.haml
  27. 26
      app/views/conferences/admin/_housing.html.haml
  28. 35
      app/views/conferences/admin/_locations.html.haml
  29. 30
      app/views/conferences/admin/_meals.html.haml
  30. 0
      app/views/conferences/admin/_schedule.html.haml
  31. 0
      app/views/conferences/admin/_stats.html.haml
  32. 23
      app/views/conferences/register.html.haml
  33. 1
      app/views/layouts/application.html.haml
  34. 4
      app/views/shared/_footer.html.haml
  35. 2
      app/views/user_mailer/broadcast.html.haml
  36. 12
      app/views/workshops/new.html.haml
  37. 2
      config/initializers/assets.rb
  38. 59
      config/locales/en.yml
  39. 2
      config/routes.rb
  40. 5
      db/migrate/20160621020123_add_space_to_event_locations.rb
  41. 5
      db/migrate/20160621051912_add_meals_to_conferences.rb
  42. 5
      db/migrate/20160622011811_add_locale_to_events.rb
  43. 5
      db/schema.rb

BIN
app/assets/images/logo-original.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

317
app/assets/images/logo-original.svg

@ -0,0 +1,317 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 792 612" style="enable-background:new 0 0 792 612;" xml:space="preserve">
<style type="text/css">
.st0{fill:#00ADEF;}
.st1{fill:#FFFFFF;}
.st2{fill:#333333;}
</style>
<path class="st0" d="M384.502,298.637c-8.782,0.887-16.889-5.133-18.436-13.966c-1.549-8.842,4.046-17.271,12.623-19.408
c-1.61-5.4-3.523-10.67-5.725-15.786c-7.953,3.86-17.648,0.982-22.131-6.797c-4.477-7.771-2.113-17.596,5.199-22.545
c-3.349-4.494-6.955-8.785-10.79-12.858c-6.153,6.325-16.229,6.93-23.095,1.163c-6.867-5.77-8.009-15.809-2.832-22.962
c-4.662-3.073-9.51-5.887-14.526-8.416c-3.608,8.067-12.881,12.098-21.315,9.025c-8.434-3.073-12.942-12.125-10.514-20.625
c-5.402-1.273-10.922-2.242-16.537-2.895c-0.64,8.806-7.969,15.756-16.938,15.756c-8.969,0-16.298-6.95-16.938-15.756
c-5.481,0.637-10.873,1.571-16.151,2.801c2.407,8.509-2.128,17.547-10.571,20.598c-8.441,3.049-17.701-1.007-21.289-9.08
c-5.022,2.516-9.879,5.313-14.549,8.373c5.156,7.17,3.986,17.202-2.896,22.953c-6.881,5.748-16.956,5.115-23.093-1.225
c-3.846,4.061-7.462,8.343-10.822,12.828c7.299,4.972,9.634,14.798,5.136,22.558c-4.504,7.767-14.204,10.617-22.146,6.739
c-2.216,5.11-4.146,10.373-5.771,15.768c8.57,2.164,14.141,10.603,12.568,19.442c-1.57,8.828-9.691,14.824-18.469,13.916
c-0.166,2.843-0.26,5.706-0.26,8.591c0,2.75,0.084,5.48,0.234,8.192c8.781-0.883,16.887,5.136,18.434,13.97
c1.548,8.842-4.047,17.266-12.621,19.404c1.61,5.4,3.522,10.669,5.725,15.785c7.952-3.857,17.646-0.979,22.129,6.801
c4.479,7.771,2.113,17.593-5.197,22.542c3.348,4.494,6.954,8.784,10.789,12.857c6.154-6.322,16.23-6.926,23.096-1.159
c6.866,5.77,8.007,15.806,2.831,22.959c4.663,3.073,9.511,5.887,14.527,8.417c3.609-8.066,12.882-12.097,21.315-9.024
c8.433,3.073,12.941,12.124,10.514,20.623c5.402,1.274,10.921,2.243,16.537,2.895c0.64-8.806,7.969-15.756,16.938-15.756
c8.969,0,16.298,6.95,16.938,15.756c5.48-0.637,10.871-1.57,16.148-2.801c-2.409-8.508,2.123-17.549,10.566-20.598
c8.44-3.049,17.708,1.005,21.293,9.082c5.023-2.516,9.88-5.314,14.551-8.373c-5.159-7.168-3.993-17.203,2.892-22.954
c6.881-5.748,16.962-5.118,23.098,1.226c3.847-4.062,7.463-8.344,10.824-12.829c-7.302-4.968-9.641-14.796-5.142-22.557
c4.503-7.765,14.209-10.621,22.15-6.74c2.216-5.11,4.147-10.372,5.772-15.768c-8.573-2.161-14.145-10.601-12.572-19.44
c1.57-8.827,9.694-14.829,18.473-13.918c0.166-2.844,0.26-5.707,0.26-8.592C384.736,304.079,384.652,301.349,384.502,298.637z"/>
<g>
<path class="st1" d="M270.605,343.041c-0.125,1.505-0.598,3.401-1.421,5.696c-0.825,2.293-1.543,4.059-2.151,5.291
c-0.612,1.234-1.204,2.401-1.779,3.506c-0.576,1.103-1.197,2.125-1.867,3.061c-4.484,5.786-10.153,9.994-17.006,12.628
c-2.637,0.97-5.372,1.672-8.211,2.097c-2.839,0.428-5.817,0.715-8.927,0.856c-1.576,0.139-3.169,0.094-4.785-0.13
c-1.617-0.223-3.179-0.397-4.681-0.52c-0.688-0.044-1.323-0.146-1.91-0.304c-0.586-0.157-1.225-0.256-1.911-0.303
c-0.557-0.007-1.11-0.155-1.661-0.445c-0.553-0.284-1.19-0.387-1.911-0.302c-0.557-0.008-1.12-0.123-1.688-0.348
c-0.569-0.221-1.181-0.42-1.831-0.595l-57.096-15.299c-2.218-0.595-4.049-1.19-5.494-1.786c-1.448-0.599-2.288-1.766-2.52-3.504
c-0.111-1.148,0.151-2.789,0.795-4.922c0.641-2.134,1.154-3.915,1.539-5.352l30.755-114.777c0.419-1.564,0.831-3.235,1.237-5.012
c0.404-1.778,1.073-3.1,2.007-3.969c0.763-0.77,1.916-1.162,3.457-1.169c0.294-0.06,0.563-0.023,0.808,0.111
c0.242,0.137,0.511,0.173,0.809,0.111l58.268,15.613c0.911,0.244,1.833,0.459,2.765,0.636c0.927,0.181,1.767,0.441,2.516,0.779
c0.58,0.438,1.214,0.676,1.902,0.72c0.686,0.045,1.337,0.22,1.955,0.524l1.174,0.314c0.712,0.471,1.498,0.787,2.365,0.947
c0.864,0.163,1.718,0.497,2.561,1.001c0.971,0.542,1.93,1.009,2.873,1.398c0.942,0.395,1.898,0.859,2.874,1.4
c2.231,1.575,4.34,3.084,6.332,4.525c1.987,1.443,3.719,3.059,5.196,4.85c2.116,2.525,3.657,5.381,4.619,8.573
c0.959,3.19,1.49,6.687,1.592,10.485c0.015,0.982-0.068,1.939-0.244,2.869c-0.182,0.931-0.281,1.951-0.298,3.063
c-0.012,0.557-0.118,1.088-0.321,1.591c-0.208,0.504-0.315,1.036-0.322,1.59c0.023,0.426-0.072,0.923-0.295,1.493
c-0.224,0.569-0.436,0.966-0.634,1.192l-0.472,1.76c-0.104,0.391-0.261,0.84-0.464,1.343c-0.208,0.505-0.343,0.888-0.411,1.146
c-0.509,0.843-0.89,1.614-1.145,2.314c-0.258,0.699-0.605,1.341-1.039,1.922c-2.953,4.238-6.198,7.491-9.739,9.755
c-1.157,0.669-2.344,1.189-3.561,1.562c-1.219,0.373-2.357,0.975-3.418,1.808c-0.334,0.192-0.722,0.472-1.168,0.839
c-0.45,0.371-0.632,0.916-0.544,1.637c-0.02,1.114,0.591,2.221,1.835,3.32c1.24,1.103,2.294,2.119,3.165,3.049
c2.891,3.289,5.023,6.795,6.402,10.518c1.281,3.558,1.969,7.515,2.06,11.867c0.112,1.15,0.083,2.295-0.081,3.437
c-0.17,1.144-0.263,2.271-0.278,3.383L270.605,343.041z"/>
<path class="st1" d="M305.286,368.469c0.606,0.864,0.818,1.896,0.635,3.105c-0.186,1.208-0.468,2.53-0.853,3.963l-3.771,14.078
c-0.385,1.436-0.801,2.72-1.244,3.858c-0.445,1.138-1.081,1.947-1.905,2.423c-1.091,0.409-2.294,0.469-3.613,0.185
c-1.322-0.282-2.7-0.618-4.132-1.002l-13.102-3.511c-1.436-0.385-2.797-0.783-4.079-1.198c-1.288-0.413-2.151-1.099-2.593-2.056
c-0.445-0.958-0.565-2.071-0.36-3.346c0.199-1.273,0.493-2.625,0.877-4.061l3.302-12.319c0.349-1.302,0.688-2.572,1.021-3.813
c0.331-1.237,0.862-2.18,1.594-2.82c0.729-0.645,1.881-1.033,3.457-1.171c0.295-0.059,0.598-0.014,0.906,0.139
c0.306,0.154,0.608,0.199,0.905,0.138l15.447,4.139c1.565,0.419,3.022,0.846,4.374,1.277
C303.504,366.911,304.547,367.574,305.286,368.469z M296.025,294.316c0.114-3.042,0.658-6.249,1.635-9.623
c0.973-3.371,1.914-6.75,2.822-10.141l4.035-15.057c0.383-1.433,0.75-2.802,1.1-4.105c0.349-1.303,0.97-2.324,1.868-3.063
c0.86-0.608,1.913-0.883,3.156-0.831c0.295-0.06,0.563-0.023,0.809,0.111c0.241,0.137,0.511,0.173,0.808,0.111l15.057,4.034
c1.564,0.42,3.013,0.879,4.348,1.376c1.332,0.497,2.201,1.29,2.61,2.376c0.311,0.921,0.312,1.97-0.003,3.143
c-0.314,1.173-0.647,2.414-0.995,3.715l-5.815,21.705c-0.21,0.781-0.382,1.678-0.512,2.691c-0.135,1.011-0.417,1.811-0.851,2.391
l-0.576,2.152c-0.508,0.843-0.858,1.761-1.054,2.756c-0.197,0.995-0.531,1.85-1,2.561c-0.438,0.583-0.701,1.174-0.791,1.778
c-0.094,0.604-0.356,1.198-0.791,1.779c-0.578,1.103-1.012,2.211-1.308,3.316c-0.298,1.11-0.718,2.15-1.257,3.122
c-0.27,0.487-0.466,0.959-0.588,1.414c-0.123,0.458-0.321,0.93-0.589,1.414c-0.717,1.626-1.384,3.332-2.001,5.122
c-0.621,1.792-1.352,3.482-2.197,5.07c-0.507,0.844-0.832,1.664-0.975,2.463c-0.145,0.8-0.488,1.686-1.025,2.659
c-1.151,2.206-2.101,4.571-2.846,7.097c-0.748,2.523-1.761,4.872-3.04,7.045c-0.88,1.723-1.607,3.518-2.177,5.389
c-0.574,1.873-1.635,3.092-3.181,3.654c-0.46,0.157-0.972,0.23-1.525,0.22c-0.558-0.009-1.179-0.035-1.864-0.081l-2.737-0.733
c-1.305-0.35-2.411-0.784-3.317-1.308c-0.908-0.522-1.537-1.18-1.883-1.971c-0.442-0.958-0.54-1.892-0.295-2.805
c0.243-0.91,0.373-1.924,0.395-3.038c-0.008-1.538,0.166-3.099,0.521-4.68c0.351-1.583,0.526-3.14,0.521-4.682
c0.279-1.041,0.404-1.776,0.381-2.203c0.078-0.817,0.224-1.616,0.434-2.399c0.209-0.78,0.351-1.582,0.432-2.398
c-0.032-1.964,0.19-3.964,0.667-6.003c0.474-2.038,0.763-4.021,0.86-5.952c0.044-0.687,0.146-1.323,0.303-1.909
c0.157-0.587,0.256-1.222,0.303-1.911c0.051-1.242,0.221-2.523,0.507-3.846c0.281-1.32,0.468-2.667,0.558-4.042
c0.07-0.26,0.107-0.527,0.113-0.808c0.001-0.277,0.041-0.545,0.111-0.809c0.016-1.113,0.159-2.157,0.421-3.135
C295.867,296.473,296.005,295.43,296.025,294.316z"/>
</g>
<g>
<path class="st2" d="M471.32,265.018c0.166,0.499,0.25,1.352,0.25,2.555c0,1.206-0.044,2.057-0.125,2.555
c0,0.418-0.021,0.77-0.063,1.06c-0.043,0.292-0.063,0.645-0.063,1.06c-0.168,0.666-0.249,1.309-0.249,1.932
c0,0.624-0.084,1.268-0.25,1.933c0,0.333-0.083,0.915-0.249,1.745c-0.249,0.997-0.48,2.016-0.686,3.054
c-0.208,1.041-0.52,2.017-0.935,2.93c-1.496,3.74-3.366,6.98-5.609,9.724c-2.244,2.742-5.195,4.904-8.852,6.482
c-0.748,0.333-1.517,0.602-2.306,0.81c-0.791,0.207-1.642,0.437-2.556,0.686c-0.499,0.166-1.019,0.25-1.559,0.25
c-0.541,0-1.06,0.041-1.559,0.124h-1.121c-0.499,0.166-1.165,0.229-1.995,0.188c-0.832-0.043-1.495-0.145-1.994-0.311h-0.748
c-0.417-0.084-0.872-0.146-1.371-0.186c-0.499-0.044-0.998-0.105-1.496-0.188c-1.579-0.417-3.034-0.832-4.363-1.246
c-1.33-0.416-2.576-0.998-3.739-1.746c-0.499-0.331-0.978-0.664-1.434-0.997c-0.458-0.331-0.895-0.705-1.31-1.122
c-0.249-0.165-0.498-0.331-0.747-0.499c-0.25-0.165-0.499-0.289-0.749-0.373c-0.748-0.25-1.205-0.082-1.371,0.498
c-0.417,0.583-0.685,1.269-0.81,2.057c-0.125,0.791-0.436,1.393-0.935,1.809c-0.498,0.332-1.081,0.52-1.745,0.56
c-0.666,0.043-1.414,0.063-2.243,0.063h-5.984c-0.582,0-1.185,0.02-1.808,0.061c-0.623,0.042-1.185-0.021-1.683-0.186
c-1.165-0.415-1.808-1.184-1.933-2.307c-0.124-1.121-0.186-2.388-0.186-3.802v-76.042c0-0.914,0-1.87,0-2.867
c0-0.997,0.206-1.786,0.623-2.369c0.331-0.581,0.913-0.955,1.745-1.122c0.166-0.082,0.353-0.103,0.562-0.062
c0.206,0.042,0.392,0.021,0.561-0.063h7.853c1.496,0,2.783,0.063,3.864,0.187c1.079,0.124,1.786,0.77,2.119,1.932
c0.25,0.832,0.332,1.932,0.25,3.304c-0.084,1.371-0.125,2.555-0.125,3.553v13.587c0,0.915,0,1.83,0,2.743
c0,0.915,0.082,1.704,0.249,2.368c0.082,0.417,0.166,0.77,0.249,1.06c0.083,0.292,0.291,0.479,0.624,0.561
c0.166,0.168,0.393,0.249,0.685,0.249c0.29,0,0.518-0.04,0.686-0.124c0.581-0.331,1.122-0.686,1.62-1.06
c0.499-0.374,1.039-0.768,1.621-1.185c1.079-0.748,2.201-1.391,3.365-1.933c1.163-0.54,2.451-1.016,3.865-1.434
c0.664-0.249,1.328-0.393,1.994-0.436c0.664-0.041,1.329-0.144,1.994-0.312c0.581-0.165,1.204-0.249,1.87-0.249
c0.665,0,1.329,0,1.995,0h1.246c0.249,0.083,0.54,0.104,0.873,0.062c0.331-0.041,0.664-0.02,0.997,0.062
c0.914,0.249,1.765,0.437,2.556,0.562c0.789,0.124,1.558,0.354,2.307,0.685c3.821,1.58,6.938,3.616,9.349,6.109
c2.41,2.493,4.445,5.609,6.108,9.349c0.415,0.997,0.768,2.037,1.06,3.116c0.291,1.081,0.602,2.204,0.935,3.366
c0.166,0.582,0.27,1.144,0.313,1.683c0.041,0.541,0.143,1.143,0.311,1.808c0.165,0.417,0.228,0.873,0.186,1.371
c-0.042,0.499-0.021,0.998,0.063,1.496V265.018z"/>
<path class="st2" d="M493.883,212.411c0.58,0.666,0.873,1.663,0.873,2.992c0,1.331,0,2.618,0,3.864c0,1.081,0,2.203,0,3.366
c0,1.165-0.293,1.954-0.873,2.369c-0.498,0.417-1.143,0.665-1.932,0.747c-0.791,0.083-1.643,0.125-2.556,0.125h-6.981
c-0.915,0-1.726-0.042-2.431-0.125c-0.707-0.082-1.309-0.331-1.808-0.747c-0.333-0.25-0.561-0.727-0.686-1.434
c-0.124-0.705-0.208-1.497-0.249-2.369c-0.043-0.872-0.043-1.765,0-2.68c0.041-0.913,0.063-1.703,0.063-2.369
c0-0.664,0.019-1.266,0.063-1.808c0.04-0.54,0.186-1.017,0.436-1.434c0.166-0.331,0.393-0.581,0.685-0.748
c0.29-0.166,0.603-0.331,0.936-0.499c0.165,0,0.374-0.02,0.623-0.063c0.249-0.04,0.456-0.062,0.623-0.062h9.101
c0.83,0,1.62,0.042,2.368,0.124C492.886,211.747,493.467,211.996,493.883,212.411z M494.756,293.565
c0,1.663-0.043,3.075-0.125,4.238c-0.083,1.165-0.831,1.953-2.243,2.369c-0.499,0.167-1.04,0.229-1.621,0.186
c-0.583-0.041-1.206-0.063-1.87-0.063h-6.98c-0.748,0-1.477-0.041-2.182-0.124c-0.707-0.082-1.228-0.332-1.559-0.749
c-0.498-0.58-0.77-1.309-0.81-2.182c-0.044-0.872-0.063-1.807-0.063-2.805v-52.606c0-0.83,0-1.661,0-2.493
c0-0.83,0.165-1.496,0.498-1.995c0.499-0.58,1.204-0.955,2.119-1.122c0.166-0.081,0.394-0.103,0.686-0.062
c0.289,0.042,0.518,0.021,0.686-0.063h6.232c0.499,0,1.06-0.019,1.683-0.063c0.624-0.041,1.142-0.02,1.559,0.063h0.997
c0.499,0.168,0.955,0.292,1.371,0.374c0.415,0.083,0.748,0.333,0.997,0.748c0.331,0.416,0.519,0.997,0.562,1.745
c0.041,0.748,0.063,1.539,0.063,2.369V293.565z"/>
<path class="st2" d="M507.471,211.539h9.1c0.914,0,1.746,0.042,2.493,0.124c0.748,0.084,1.328,0.333,1.746,0.748
c0.663,0.748,0.976,1.954,0.935,3.615c-0.043,1.663-0.063,3.2-0.063,4.612v21.067v7.604c0,0.582-0.043,1.206-0.125,1.87
c-0.084,0.666-0.042,1.289,0.125,1.87v1.122c0.165,0.416,0.29,0.854,0.374,1.309c0.082,0.458,0.331,0.77,0.748,0.935
c0.249,0.168,0.58,0.187,0.997,0.062c0.415-0.125,0.705-0.269,0.872-0.436c0.83-0.58,1.558-1.246,2.182-1.995
c0.624-0.748,1.267-1.453,1.933-2.119c0.664-0.663,1.371-1.35,2.119-2.057c0.748-0.705,1.412-1.474,1.994-2.306
c0.25-0.165,0.54-0.414,0.873-0.748c0.415-0.415,0.83-0.851,1.246-1.309c0.416-0.456,0.83-0.892,1.247-1.309l2.867-2.867
c0.166-0.331,0.393-0.602,0.685-0.81c0.29-0.207,0.562-0.478,0.811-0.811c0.664-0.83,1.391-1.559,2.182-2.182
c0.788-0.624,1.765-1.06,2.929-1.309c0.416-0.081,0.998-0.124,1.746-0.124c0.331-0.082,0.664-0.103,0.997-0.063
c0.331,0.043,0.705,0.063,1.122,0.063h4.113c0.665,0,1.475-0.041,2.432-0.125c0.954-0.082,1.764-0.041,2.431,0.125h1.371
c0.415,0.168,0.829,0.27,1.247,0.312c0.414,0.043,0.705,0.229,0.872,0.561c0.166,0.249,0.188,0.582,0.063,0.997
c-0.125,0.417-0.271,0.707-0.437,0.873c-0.498,0.831-1.122,1.558-1.87,2.181c-0.748,0.624-1.455,1.268-2.119,1.933
c-0.582,0.582-1.143,1.165-1.683,1.745c-0.541,0.583-1.144,1.122-1.808,1.621c-0.417,0.333-0.77,0.686-1.06,1.059
c-0.292,0.374-0.645,0.729-1.06,1.06c-0.417,0.249-0.791,0.583-1.122,0.997c-0.333,0.417-0.707,0.791-1.122,1.122l-4.737,4.737
c-0.582,0.499-1.102,0.978-1.558,1.434c-0.458,0.458-0.895,1.019-1.309,1.683c-0.168,0.249-0.334,0.561-0.499,0.935
c-0.168,0.374-0.168,0.769,0,1.185c0.165,0.916,0.477,1.663,0.934,2.244c0.456,0.582,0.893,1.206,1.309,1.87
c0.665,0.916,1.267,1.829,1.809,2.742c0.539,0.916,1.141,1.829,1.808,2.742l13.089,19.821c0.83,1.165,1.64,2.327,2.431,3.49
c0.789,1.165,1.516,2.328,2.182,3.49c0.249,0.417,0.394,0.916,0.435,1.496c0.041,0.583-0.146,1.041-0.56,1.372
c-0.333,0.167-0.666,0.249-0.997,0.249c-0.333,0-0.707,0.083-1.122,0.249c-0.333,0.084-0.707,0.105-1.122,0.063
c-0.416-0.041-0.831-0.063-1.246-0.063h-4.862c-1.33,0-2.91,0.022-4.736,0.063c-1.829,0.043-3.201-0.145-4.114-0.56
c-0.915-0.416-1.704-1.185-2.368-2.307c-0.666-1.122-1.289-2.139-1.87-3.055c-1.414-2.243-2.826-4.507-4.238-6.794
c-1.414-2.284-2.826-4.55-4.238-6.794c-0.667-1.079-1.31-2.16-1.933-3.241c-0.623-1.079-1.308-2.119-2.057-3.116
c-0.168-0.249-0.458-0.58-0.873-0.997c-0.417-0.415-0.872-0.54-1.371-0.374c-0.748,0.168-1.309,0.417-1.683,0.748
c-0.374,0.333-0.769,0.707-1.185,1.122c-0.666,0.498-1.289,1.081-1.869,1.745c-0.583,0.666-1.041,1.455-1.372,2.369
c-0.167,0.665-0.249,1.392-0.249,2.181c0,0.791,0,1.559,0,2.307v7.729c0,0.582,0.02,1.228,0.063,1.933
c0.041,0.707,0.063,1.434,0.063,2.182c0,0.747-0.043,1.434-0.125,2.057c-0.084,0.623-0.249,1.103-0.498,1.434
c-0.334,0.498-0.854,0.853-1.559,1.06c-0.707,0.208-1.518,0.333-2.432,0.374c-0.915,0.043-1.869,0.043-2.867,0
c-0.997-0.041-1.869-0.063-2.617-0.063c-0.915,0-1.913,0.022-2.992,0.063c-1.081,0.043-1.953-0.063-2.618-0.311
c-1.081-0.415-1.663-1.163-1.745-2.244c-0.083-1.079-0.124-2.326-0.124-3.74v-14.335v-49.989v-11.593
c0-0.914-0.021-1.87-0.063-2.867c-0.043-0.997,0.103-1.786,0.436-2.369c0.331-0.581,0.913-0.997,1.745-1.247
c0.166,0,0.353-0.02,0.561-0.063C507.116,211.56,507.303,211.539,507.471,211.539z"/>
<path class="st2" d="M628.888,267.635c0.165,0.667,0.165,1.414,0,2.244c-0.168,0.832-0.458,1.372-0.873,1.621
c-0.417,0.333-1.018,0.561-1.808,0.686c-0.79,0.125-1.663,0.208-2.618,0.25c-0.956,0.043-1.912,0.043-2.867,0
c-0.956-0.041-1.808-0.063-2.555-0.063H587.75c-0.583,0-1.144,0-1.684,0c-0.541,0-1.018,0.083-1.434,0.25
c-0.665,0.333-1.081,0.666-1.246,0.997c-0.168,0.167-0.333,0.48-0.499,0.935c-0.167,0.458-0.208,0.894-0.124,1.309
c0.165,0.499,0.268,0.978,0.312,1.435c0.041,0.457,0.144,0.935,0.311,1.434c0.664,1.994,1.475,3.636,2.431,4.924
c0.954,1.289,2.264,2.431,3.927,3.428c0.664,0.417,1.35,0.686,2.057,0.811c0.705,0.125,1.434,0.311,2.182,0.56
c0.664,0.168,1.578,0.293,2.743,0.374c1.162,0.084,2.16,0.043,2.991-0.125h1.122c0.83-0.165,1.6-0.352,2.307-0.56
c0.705-0.206,1.391-0.436,2.057-0.686c0.83-0.415,1.765-0.954,2.805-1.621c1.038-0.663,1.808-1.328,2.307-1.994
c0.414-0.58,0.851-1.142,1.309-1.683c0.456-0.54,1.017-0.936,1.683-1.185c0.83-0.415,1.89-0.602,3.18-0.561
c1.287,0.042,2.471,0.062,3.552,0.062c0.499,0,1.017-0.02,1.559-0.062c0.539-0.041,1.017,0.022,1.434,0.187h1.247
c0.829,0.168,1.412,0.374,1.745,0.623c0.331,0.168,0.518,0.542,0.561,1.122c0.041,0.583-0.021,1.081-0.187,1.496
c-0.417,1.165-0.873,2.203-1.372,3.117c-0.498,0.915-1.081,1.828-1.745,2.742c-1.829,2.742-3.907,4.945-6.232,6.606
c-2.328,1.663-5.236,3.075-8.727,4.239c-0.915,0.331-1.828,0.539-2.742,0.623c-0.916,0.082-1.87,0.249-2.867,0.498
c-0.333,0.082-0.686,0.104-1.06,0.063c-0.374-0.043-0.729-0.021-1.06,0.063h-1.371c-0.417,0.166-0.895,0.228-1.434,0.186
c-0.542-0.043-1.02-0.104-1.434-0.186c-0.666-0.084-1.247-0.084-1.746,0c-0.498,0.082-1.04,0.041-1.62-0.125
c-0.417-0.167-0.872-0.249-1.371-0.249c-0.498,0-0.956-0.084-1.371-0.249c-0.915-0.168-1.829-0.355-2.743-0.562
c-0.915-0.206-1.744-0.518-2.493-0.934c-0.915-0.331-1.767-0.644-2.556-0.935c-0.79-0.291-1.517-0.644-2.181-1.06
c-2.661-1.662-5.029-3.594-7.106-5.797c-2.078-2.201-3.782-4.757-5.11-7.667c-0.417-0.913-0.748-1.849-0.997-2.805
c-0.25-0.955-0.582-1.933-0.998-2.93c-0.083-0.331-0.124-0.643-0.124-0.935c0-0.291-0.043-0.602-0.125-0.935
c-0.333-0.997-0.541-2.076-0.623-3.241c-0.084-1.163-0.168-2.326-0.249-3.491c0-0.415-0.021-0.873-0.063-1.371
c-0.043-0.499-0.021-0.955,0.063-1.371v-1.496l0.373-2.992c0.332-1.412,0.624-2.783,0.873-4.114
c0.249-1.328,0.623-2.575,1.122-3.739c3.572-8.643,9.64-14.751,18.2-18.325c1.163-0.499,2.347-0.851,3.553-1.06
c1.204-0.206,2.472-0.477,3.802-0.811c0.665-0.081,1.288-0.124,1.87-0.124c0.581,0,1.204-0.042,1.87-0.125
c4.238-0.082,7.873,0.395,10.907,1.434c3.033,1.04,5.755,2.39,8.166,4.052c0.747,0.499,1.495,1.06,2.244,1.683
c0.747,0.624,1.412,1.268,1.994,1.932c0.249,0.417,0.58,0.748,0.997,0.997c0.664,0.916,1.288,1.85,1.87,2.805
c0.58,0.957,1.204,1.932,1.869,2.93c0.416,0.748,0.769,1.517,1.06,2.306c0.291,0.79,0.602,1.642,0.936,2.555
c0.415,1.081,0.748,2.203,0.997,3.366c0.249,1.165,0.54,2.328,0.873,3.49c0.165,0.666,0.228,1.393,0.187,2.182
c-0.043,0.79,0.019,1.517,0.188,2.182V267.635z"/>
<path class="st2" d="M652.571,282.096c0.499,0.417,0.789,0.997,0.873,1.745c0.081,0.748,0.124,1.58,0.124,2.493v8.976
c0,0.916-0.043,1.745-0.124,2.493c-0.084,0.748-0.333,1.33-0.748,1.745c-0.583,0.417-1.29,0.645-2.119,0.685
c-0.832,0.043-1.705,0.063-2.618,0.063h-8.353c-0.915,0-1.788-0.02-2.617-0.063c-0.832-0.041-1.456-0.311-1.87-0.81
c-0.417-0.498-0.666-1.141-0.748-1.932c-0.084-0.789-0.125-1.641-0.125-2.556v-7.853c0-0.829,0-1.64,0-2.431
c0-0.789,0.166-1.434,0.499-1.933c0.331-0.498,0.954-0.913,1.87-1.246c0.165-0.082,0.353-0.104,0.561-0.063
c0.207,0.043,0.393,0.021,0.562-0.063h9.848c0.997,0,1.933,0.021,2.805,0.063C651.263,281.453,651.989,281.681,652.571,282.096z
M635.244,239.462c-0.417-1.828-0.604-3.822-0.562-5.984c0.041-2.16,0.063-4.32,0.063-6.482v-9.599c0-0.914,0-1.786,0-2.618
c0-0.83,0.206-1.537,0.623-2.12c0.415-0.499,0.997-0.83,1.745-0.997c0.166-0.082,0.331-0.103,0.499-0.063
c0.165,0.043,0.331,0.021,0.499-0.062h9.599c0.997,0,1.932,0.042,2.805,0.124c0.872,0.084,1.516,0.417,1.932,0.997
c0.331,0.499,0.499,1.122,0.499,1.87c0,0.748,0,1.538,0,2.369v13.837c0,0.499,0.041,1.06,0.125,1.683
c0.081,0.624,0.041,1.144-0.125,1.558v1.372c-0.168,0.582-0.23,1.184-0.188,1.808c0.041,0.623-0.021,1.184-0.187,1.683
c-0.167,0.417-0.229,0.811-0.187,1.185c0.04,0.374-0.021,0.769-0.188,1.184c-0.167,0.749-0.249,1.477-0.249,2.182
c0,0.707-0.084,1.392-0.249,2.057c-0.084,0.333-0.125,0.645-0.125,0.935c0,0.292-0.043,0.604-0.125,0.936
c-0.167,1.081-0.292,2.203-0.374,3.365c-0.084,1.165-0.249,2.287-0.498,3.366c-0.168,0.583-0.23,1.122-0.188,1.621
c0.041,0.499-0.021,1.081-0.187,1.746c-0.333,1.496-0.521,3.054-0.561,4.675c-0.043,1.62-0.271,3.179-0.686,4.675
c-0.249,1.164-0.396,2.349-0.437,3.552c-0.043,1.206-0.478,2.1-1.309,2.68c-0.25,0.168-0.541,0.293-0.873,0.375
c-0.333,0.083-0.707,0.167-1.121,0.249h-1.746c-0.831,0-1.558-0.082-2.181-0.249c-0.624-0.165-1.102-0.456-1.434-0.872
c-0.417-0.499-0.624-1.038-0.624-1.621c0-0.581-0.083-1.204-0.249-1.87c-0.249-0.913-0.396-1.87-0.437-2.867
c-0.043-0.998-0.186-1.952-0.436-2.867c0-0.664-0.043-1.122-0.125-1.371c-0.084-0.499-0.125-0.997-0.125-1.496
c0-0.498-0.043-0.998-0.124-1.496c-0.333-1.163-0.521-2.388-0.562-3.678c-0.043-1.287-0.187-2.513-0.437-3.678
c-0.083-0.414-0.124-0.81-0.124-1.184c0-0.374-0.043-0.768-0.125-1.185c-0.168-0.748-0.271-1.537-0.311-2.369
c-0.043-0.83-0.147-1.661-0.312-2.493c0-0.165-0.021-0.331-0.063-0.499c-0.043-0.165-0.063-0.331-0.063-0.499
c-0.167-0.664-0.249-1.309-0.249-1.932C635.493,240.771,635.409,240.128,635.244,239.462z"/>
</g>
<g>
<path class="st2" d="M471.32,363.343c0.166,0.499,0.25,1.352,0.25,2.556c0,1.206-0.044,2.057-0.125,2.555
c0,0.418-0.021,0.771-0.063,1.06c-0.043,0.293-0.063,0.646-0.063,1.061c-0.168,0.666-0.249,1.309-0.249,1.933
c0,0.623-0.084,1.268-0.25,1.932c0,0.333-0.083,0.916-0.249,1.745c-0.249,0.998-0.48,2.017-0.686,3.055
c-0.208,1.04-0.52,2.016-0.935,2.93c-1.496,3.739-3.366,6.98-5.609,9.723c-2.244,2.743-5.195,4.905-8.852,6.483
c-0.748,0.333-1.517,0.603-2.306,0.81c-0.791,0.207-1.642,0.438-2.556,0.687c-0.499,0.166-1.019,0.249-1.559,0.249
c-0.541,0-1.06,0.041-1.559,0.124h-1.121c-0.499,0.167-1.165,0.228-1.995,0.188c-0.832-0.042-1.495-0.146-1.994-0.312h-0.748
c-0.417-0.083-0.872-0.145-1.371-0.186c-0.499-0.044-0.998-0.105-1.496-0.188c-1.579-0.416-3.034-0.831-4.363-1.246
c-1.33-0.415-2.576-0.997-3.739-1.745c-0.499-0.331-0.978-0.664-1.434-0.997c-0.458-0.332-0.895-0.705-1.31-1.122
c-0.249-0.166-0.498-0.331-0.747-0.499c-0.25-0.165-0.499-0.29-0.749-0.374c-0.748-0.249-1.205-0.082-1.371,0.499
c-0.417,0.582-0.685,1.268-0.81,2.056c-0.125,0.792-0.436,1.393-0.935,1.808c-0.498,0.332-1.081,0.52-1.745,0.561
c-0.666,0.043-1.414,0.063-2.243,0.063h-5.984c-0.582,0-1.185,0.02-1.808,0.061c-0.623,0.042-1.185-0.02-1.683-0.185
c-1.165-0.415-1.808-1.185-1.933-2.308c-0.124-1.121-0.186-2.387-0.186-3.801v-76.043c0-0.914,0-1.869,0-2.867
c0-0.997,0.206-1.786,0.623-2.368c0.331-0.581,0.913-0.955,1.745-1.122c0.166-0.082,0.353-0.103,0.562-0.063
c0.206,0.043,0.392,0.021,0.561-0.062h7.853c1.496,0,2.783,0.062,3.864,0.187c1.079,0.124,1.786,0.77,2.119,1.933
c0.25,0.831,0.332,1.932,0.25,3.303c-0.084,1.372-0.125,2.556-0.125,3.553v13.588c0,0.915,0,1.829,0,2.743
c0,0.915,0.082,1.703,0.249,2.368c0.082,0.416,0.166,0.769,0.249,1.06c0.083,0.292,0.291,0.479,0.624,0.562
c0.166,0.167,0.393,0.248,0.685,0.248c0.29,0,0.518-0.041,0.686-0.124c0.581-0.331,1.122-0.686,1.62-1.06
c0.499-0.374,1.039-0.768,1.621-1.184c1.079-0.748,2.201-1.392,3.365-1.934c1.163-0.539,2.451-1.016,3.865-1.434
c0.664-0.248,1.328-0.393,1.994-0.436c0.664-0.041,1.329-0.143,1.994-0.311c0.581-0.165,1.204-0.249,1.87-0.249
c0.665,0,1.329,0,1.995,0h1.246c0.249,0.084,0.54,0.105,0.873,0.063c0.331-0.041,0.664-0.02,0.997,0.062
c0.914,0.25,1.765,0.436,2.556,0.561c0.789,0.124,1.558,0.354,2.307,0.685c3.821,1.58,6.938,3.616,9.349,6.109
c2.41,2.493,4.445,5.609,6.108,9.35c0.415,0.997,0.768,2.036,1.06,3.115c0.291,1.081,0.602,2.204,0.935,3.366
c0.166,0.583,0.27,1.144,0.313,1.684c0.041,0.541,0.143,1.144,0.311,1.808c0.165,0.417,0.228,0.872,0.186,1.37
c-0.042,0.499-0.021,0.998,0.063,1.497V363.343z"/>
<path class="st2" d="M493.883,310.736c0.58,0.667,0.873,1.664,0.873,2.992c0,1.33,0,2.618,0,3.864c0,1.081,0,2.203,0,3.365
c0,1.166-0.293,1.954-0.873,2.369c-0.498,0.417-1.143,0.666-1.932,0.748c-0.791,0.083-1.643,0.125-2.556,0.125h-6.981
c-0.915,0-1.726-0.042-2.431-0.125c-0.707-0.082-1.309-0.331-1.808-0.748c-0.333-0.25-0.561-0.727-0.686-1.434
c-0.124-0.705-0.208-1.496-0.249-2.369c-0.043-0.872-0.043-1.764,0-2.68c0.041-0.913,0.063-1.702,0.063-2.369
c0-0.663,0.019-1.265,0.063-1.807c0.04-0.539,0.186-1.017,0.436-1.434c0.166-0.332,0.393-0.581,0.685-0.748
c0.29-0.165,0.603-0.331,0.936-0.498c0.165,0,0.374-0.02,0.623-0.063c0.249-0.041,0.456-0.063,0.623-0.063h9.101
c0.83,0,1.62,0.043,2.368,0.125C492.886,310.072,493.467,310.322,493.883,310.736z M494.756,391.89
c0,1.664-0.043,3.076-0.125,4.238c-0.083,1.165-0.831,1.954-2.243,2.369c-0.499,0.167-1.04,0.229-1.621,0.186
c-0.583-0.041-1.206-0.061-1.87-0.061h-6.98c-0.748,0-1.477-0.041-2.182-0.125c-0.707-0.082-1.228-0.331-1.559-0.749
c-0.498-0.579-0.77-1.308-0.81-2.181c-0.044-0.872-0.063-1.808-0.063-2.806v-52.605c0-0.83,0-1.661,0-2.493
c0-0.83,0.165-1.496,0.498-1.994c0.499-0.581,1.204-0.955,2.119-1.123c0.166-0.081,0.394-0.103,0.686-0.061
c0.289,0.042,0.518,0.021,0.686-0.063h6.232c0.499,0,1.06-0.02,1.683-0.063c0.624-0.041,1.142-0.02,1.559,0.063h0.997
c0.499,0.168,0.955,0.292,1.371,0.374c0.415,0.083,0.748,0.333,0.997,0.748c0.331,0.416,0.519,0.997,0.562,1.745
c0.041,0.748,0.063,1.538,0.063,2.369V391.89z"/>
<path class="st2" d="M507.471,309.864h9.1c0.914,0,1.746,0.043,2.493,0.125c0.748,0.083,1.328,0.333,1.746,0.747
c0.663,0.748,0.976,1.954,0.935,3.615c-0.043,1.663-0.063,3.2-0.063,4.612v21.068v7.604c0,0.583-0.043,1.206-0.125,1.869
c-0.084,0.667-0.042,1.29,0.125,1.871v1.122c0.165,0.416,0.29,0.853,0.374,1.308c0.082,0.459,0.331,0.771,0.748,0.936
c0.249,0.168,0.58,0.188,0.997,0.063c0.415-0.125,0.705-0.27,0.872-0.437c0.83-0.581,1.558-1.246,2.182-1.995
c0.624-0.747,1.267-1.452,1.933-2.119c0.664-0.663,1.371-1.349,2.119-2.056c0.748-0.705,1.412-1.475,1.994-2.307
c0.25-0.165,0.54-0.415,0.873-0.748c0.415-0.415,0.83-0.851,1.246-1.309c0.416-0.456,0.83-0.893,1.247-1.309l2.867-2.867
c0.166-0.332,0.393-0.603,0.685-0.811c0.29-0.207,0.562-0.478,0.811-0.811c0.664-0.83,1.391-1.559,2.182-2.182
c0.788-0.624,1.765-1.06,2.929-1.31c0.416-0.081,0.998-0.124,1.746-0.124c0.331-0.082,0.664-0.104,0.997-0.063
c0.331,0.043,0.705,0.063,1.122,0.063h4.113c0.665,0,1.475-0.041,2.432-0.124c0.954-0.082,1.764-0.041,2.431,0.124h1.371
c0.415,0.168,0.829,0.271,1.247,0.311c0.414,0.043,0.705,0.23,0.872,0.561c0.166,0.249,0.188,0.582,0.063,0.996
c-0.125,0.418-0.271,0.707-0.437,0.874c-0.498,0.831-1.122,1.558-1.87,2.181c-0.748,0.624-1.455,1.268-2.119,1.933
c-0.582,0.582-1.143,1.165-1.683,1.745c-0.541,0.582-1.144,1.121-1.808,1.621c-0.417,0.333-0.77,0.686-1.06,1.06
c-0.292,0.374-0.645,0.728-1.06,1.06c-0.417,0.248-0.791,0.582-1.122,0.996c-0.333,0.418-0.707,0.792-1.122,1.123l-4.737,4.736
c-0.582,0.499-1.102,0.979-1.558,1.434c-0.458,0.458-0.895,1.02-1.309,1.684c-0.168,0.249-0.334,0.561-0.499,0.935
c-0.168,0.374-0.168,0.769,0,1.185c0.165,0.915,0.477,1.663,0.934,2.244c0.456,0.581,0.893,1.205,1.309,1.869
c0.665,0.916,1.267,1.829,1.809,2.743c0.539,0.915,1.141,1.828,1.808,2.741l13.089,19.821c0.83,1.165,1.64,2.327,2.431,3.491
c0.789,1.164,1.516,2.327,2.182,3.489c0.249,0.418,0.394,0.916,0.435,1.497c0.041,0.582-0.146,1.04-0.56,1.371
c-0.333,0.167-0.666,0.249-0.997,0.249c-0.333,0-0.707,0.083-1.122,0.25c-0.333,0.083-0.707,0.104-1.122,0.061
c-0.416-0.041-0.831-0.061-1.246-0.061h-4.862c-1.33,0-2.91,0.021-4.736,0.061c-1.829,0.043-3.201-0.144-4.114-0.561
c-0.915-0.415-1.704-1.184-2.368-2.307c-0.666-1.121-1.289-2.139-1.87-3.055c-1.414-2.243-2.826-4.506-4.238-6.794
c-1.414-2.284-2.826-4.549-4.238-6.794c-0.667-1.079-1.31-2.159-1.933-3.24c-0.623-1.079-1.308-2.12-2.057-3.116
c-0.168-0.25-0.458-0.581-0.873-0.997c-0.417-0.415-0.872-0.54-1.371-0.374c-0.748,0.167-1.309,0.416-1.683,0.747
c-0.374,0.334-0.769,0.708-1.185,1.122c-0.666,0.498-1.289,1.081-1.869,1.745c-0.583,0.667-1.041,1.455-1.372,2.369
c-0.167,0.665-0.249,1.392-0.249,2.182c0,0.791,0,1.558,0,2.306v7.73c0,0.582,0.02,1.226,0.063,1.932
c0.041,0.707,0.063,1.434,0.063,2.182c0,0.748-0.043,1.434-0.125,2.057c-0.084,0.624-0.249,1.103-0.498,1.434
c-0.334,0.498-0.854,0.853-1.559,1.06c-0.707,0.209-1.518,0.333-2.432,0.374c-0.915,0.043-1.869,0.043-2.867,0
c-0.997-0.041-1.869-0.061-2.617-0.061c-0.915,0-1.913,0.021-2.992,0.061c-1.081,0.043-1.953-0.061-2.618-0.311
c-1.081-0.415-1.663-1.163-1.745-2.244c-0.083-1.078-0.124-2.326-0.124-3.74v-14.335v-49.989v-11.593
c0-0.914-0.021-1.869-0.063-2.867c-0.043-0.997,0.103-1.786,0.436-2.368c0.331-0.581,0.913-0.997,1.745-1.246
c0.166,0,0.353-0.02,0.561-0.063C507.116,309.886,507.303,309.864,507.471,309.864z"/>
<path class="st2" d="M628.888,365.96c0.165,0.667,0.165,1.414,0,2.245c-0.168,0.831-0.458,1.371-0.873,1.62
c-0.417,0.333-1.018,0.561-1.808,0.686c-0.79,0.125-1.663,0.209-2.618,0.25c-0.956,0.042-1.912,0.042-2.867,0
c-0.956-0.041-1.808-0.063-2.555-0.063H587.75c-0.583,0-1.144,0-1.684,0c-0.541,0-1.018,0.083-1.434,0.248
c-0.665,0.334-1.081,0.667-1.246,0.998c-0.168,0.168-0.333,0.479-0.499,0.936c-0.167,0.457-0.208,0.893-0.124,1.308
c0.165,0.499,0.268,0.978,0.312,1.435c0.041,0.458,0.144,0.935,0.311,1.434c0.664,1.994,1.475,3.637,2.431,4.924
c0.954,1.289,2.264,2.431,3.927,3.428c0.664,0.417,1.35,0.687,2.057,0.811c0.705,0.125,1.434,0.311,2.182,0.561
c0.664,0.167,1.578,0.292,2.743,0.374c1.162,0.083,2.16,0.043,2.991-0.126h1.122c0.83-0.165,1.6-0.353,2.307-0.56
c0.705-0.207,1.391-0.436,2.057-0.686c0.83-0.414,1.765-0.954,2.805-1.62c1.038-0.664,1.808-1.328,2.307-1.994
c0.414-0.581,0.851-1.142,1.309-1.684c0.456-0.539,1.017-0.935,1.683-1.184c0.83-0.415,1.89-0.603,3.18-0.561
c1.287,0.043,2.471,0.061,3.552,0.061c0.499,0,1.017-0.018,1.559-0.061c0.539-0.041,1.017,0.021,1.434,0.188h1.247
c0.829,0.167,1.412,0.374,1.745,0.622c0.331,0.168,0.518,0.542,0.561,1.123c0.041,0.582-0.021,1.081-0.187,1.496
c-0.417,1.164-0.873,2.202-1.372,3.116c-0.498,0.915-1.081,1.829-1.745,2.742c-1.829,2.743-3.907,4.945-6.232,6.607
c-2.328,1.663-5.236,3.075-8.727,4.238c-0.915,0.331-1.828,0.539-2.742,0.623c-0.916,0.082-1.87,0.249-2.867,0.499
c-0.333,0.081-0.686,0.103-1.06,0.063c-0.374-0.043-0.729-0.021-1.06,0.061h-1.371c-0.417,0.166-0.895,0.229-1.434,0.188
c-0.542-0.044-1.02-0.105-1.434-0.188c-0.666-0.083-1.247-0.083-1.746,0c-0.498,0.082-1.04,0.041-1.62-0.124
c-0.417-0.168-0.872-0.25-1.371-0.25c-0.498,0-0.956-0.083-1.371-0.249c-0.915-0.167-1.829-0.355-2.743-0.561
c-0.915-0.207-1.744-0.519-2.493-0.936c-0.915-0.331-1.767-0.642-2.556-0.934c-0.79-0.29-1.517-0.643-2.181-1.06
c-2.661-1.661-5.029-3.594-7.106-5.797c-2.078-2.201-3.782-4.757-5.11-7.666c-0.417-0.914-0.748-1.849-0.997-2.806
c-0.25-0.954-0.582-1.932-0.998-2.929c-0.083-0.331-0.124-0.644-0.124-0.936c0-0.29-0.043-0.602-0.125-0.935
c-0.333-0.997-0.541-2.076-0.623-3.241c-0.084-1.163-0.168-2.326-0.249-3.49c0-0.415-0.021-0.873-0.063-1.372
c-0.043-0.498-0.021-0.954,0.063-1.371v-1.496l0.373-2.992c0.332-1.411,0.624-2.782,0.873-4.113
c0.249-1.328,0.623-2.574,1.122-3.739c3.572-8.643,9.64-14.751,18.2-18.325c1.163-0.498,2.347-0.851,3.553-1.06
c1.204-0.206,2.472-0.478,3.802-0.81c0.665-0.081,1.288-0.124,1.87-0.124c0.581,0,1.204-0.042,1.87-0.125
c4.238-0.082,7.873,0.395,10.907,1.434c3.033,1.04,5.755,2.39,8.166,4.052c0.747,0.498,1.495,1.06,2.244,1.683
c0.747,0.623,1.412,1.268,1.994,1.933c0.249,0.416,0.58,0.748,0.997,0.997c0.664,0.915,1.288,1.851,1.87,2.804
c0.58,0.957,1.204,1.934,1.869,2.931c0.416,0.748,0.769,1.518,1.06,2.306c0.291,0.791,0.602,1.642,0.936,2.556
c0.415,1.081,0.748,2.203,0.997,3.366c0.249,1.164,0.54,2.327,0.873,3.489c0.165,0.667,0.228,1.394,0.187,2.183
c-0.043,0.791,0.019,1.518,0.188,2.182V365.96z"/>
<path class="st2" d="M652.571,380.421c0.499,0.417,0.789,0.998,0.873,1.746c0.081,0.747,0.124,1.579,0.124,2.493v8.975
c0,0.916-0.043,1.746-0.124,2.493c-0.084,0.748-0.333,1.331-0.748,1.746c-0.583,0.416-1.29,0.645-2.119,0.686
c-0.832,0.043-1.705,0.063-2.618,0.063h-8.353c-0.915,0-1.788-0.02-2.617-0.063c-0.832-0.041-1.456-0.312-1.87-0.812
c-0.417-0.498-0.666-1.141-0.748-1.932c-0.084-0.788-0.125-1.641-0.125-2.555v-7.854c0-0.829,0-1.64,0-2.431
c0-0.788,0.166-1.434,0.499-1.932c0.331-0.499,0.954-0.914,1.87-1.247c0.165-0.082,0.353-0.104,0.561-0.063
c0.207,0.043,0.393,0.021,0.562-0.062h9.848c0.997,0,1.933,0.021,2.805,0.062C651.263,379.778,651.989,380.007,652.571,380.421z
M635.244,337.788c-0.417-1.828-0.604-3.822-0.562-5.983c0.041-2.16,0.063-4.32,0.063-6.482v-9.599c0-0.914,0-1.786,0-2.618
c0-0.83,0.206-1.537,0.623-2.119c0.415-0.499,0.997-0.83,1.745-0.997c0.166-0.082,0.331-0.104,0.499-0.063
c0.165,0.043,0.331,0.021,0.499-0.063h9.599c0.997,0,1.932,0.043,2.805,0.125c0.872,0.083,1.516,0.416,1.932,0.997
c0.331,0.498,0.499,1.122,0.499,1.87c0,0.747,0,1.538,0,2.368v13.837c0,0.499,0.041,1.06,0.125,1.683
c0.081,0.624,0.041,1.144-0.125,1.559v1.371c-0.168,0.583-0.23,1.184-0.188,1.808c0.041,0.623-0.021,1.184-0.187,1.684
c-0.167,0.416-0.229,0.81-0.187,1.184c0.04,0.374-0.021,0.77-0.188,1.184c-0.167,0.749-0.249,1.478-0.249,2.183
c0,0.707-0.084,1.392-0.249,2.057c-0.084,0.333-0.125,0.644-0.125,0.935c0,0.293-0.043,0.604-0.125,0.936
c-0.167,1.081-0.292,2.203-0.374,3.365c-0.084,1.165-0.249,2.286-0.498,3.365c-0.168,0.583-0.23,1.123-0.188,1.621
c0.041,0.499-0.021,1.081-0.187,1.746c-0.333,1.495-0.521,3.053-0.561,4.674c-0.043,1.62-0.271,3.18-0.686,4.675
c-0.249,1.165-0.396,2.35-0.437,3.553c-0.043,1.206-0.478,2.101-1.309,2.68c-0.25,0.168-0.541,0.293-0.873,0.375
c-0.333,0.084-0.707,0.167-1.121,0.249h-1.746c-0.831,0-1.558-0.082-2.181-0.249c-0.624-0.166-1.102-0.456-1.434-0.873
c-0.417-0.498-0.624-1.038-0.624-1.62c0-0.581-0.083-1.204-0.249-1.87c-0.249-0.913-0.396-1.87-0.437-2.867
c-0.043-0.998-0.186-1.951-0.436-2.867c0-0.665-0.043-1.122-0.125-1.372c-0.084-0.498-0.125-0.996-0.125-1.495
c0-0.498-0.043-0.998-0.124-1.496c-0.333-1.162-0.521-2.388-0.562-3.677c-0.043-1.288-0.187-2.513-0.437-3.679
c-0.083-0.414-0.124-0.81-0.124-1.184c0-0.374-0.043-0.768-0.125-1.184c-0.168-0.748-0.271-1.538-0.311-2.369
c-0.043-0.829-0.147-1.661-0.312-2.493c0-0.165-0.021-0.331-0.063-0.498c-0.043-0.166-0.063-0.332-0.063-0.5
c-0.167-0.663-0.249-1.308-0.249-1.932C635.493,339.097,635.409,338.453,635.244,337.788z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 33 KiB

2407
app/assets/images/logo.ai

File diff suppressed because one or more lines are too long

BIN
app/assets/images/runes.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

19
app/assets/javascripts/editor.js

@ -2,7 +2,19 @@
var pens = {};
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(editor) {
startEditing(editor);
var event= editor.dataset.editOn;
if (event == 'load') {
startEditing(editor);
} else {
editor.addEventListener(event, function() {
if (editor.getAttribute('contenteditable') !== 'true') {
startEditing(editor);
// for content editable, we need to refocus to show the caret
editor.blur();
editor.focus();
}
});
}
});
function startEditing(editor) {
@ -27,6 +39,7 @@
'insertimage': 'Image'
}
});
return pens[name];
}
Array.prototype.forEach.call(document.querySelectorAll('form'), function(form) {
@ -45,7 +58,9 @@
form.appendChild(textarea);
}
textarea.value = editor.innerHTML;
pens[name].destroy();
if (pens[name]) {
pens[name].destroy();
}
});
}, false);
Array.prototype.forEach.call(form.querySelectorAll('button'), function(button) {

82
app/assets/javascripts/housing.js

@ -0,0 +1,82 @@
(function() {
function closeOnTop() {
document.documentElement.removeAttribute('data-ontop');
document.getElementById('guest_id').value = '';
var target = document.querySelector('.on-top-target');
target.removeAttribute('style');
document.querySelector('body').removeAttribute('style');
forEachElement('.on-top-control', function(control) {
control.classList.remove('on-top-control');
});
}
forEachElement('#guests .guest', function(guest) {
var button = guest.querySelector('.set-host');
button.addEventListener('click', function(event) {
var target = document.querySelector('.on-top-target');
var body = document.querySelector('body');
// maintain our current height
body.setAttribute('style', 'height: ' + body.clientHeight + 'px');
document.documentElement.setAttribute('data-ontop', 'set-host');
guest.classList.add('on-top-control');
target.setAttribute('style', 'bottom: ' + guest.clientHeight + 'px');
document.getElementById('guest_id').value = guest.dataset.id;
});
});
forEachElement('#hosts .host', function(host) {
initHost(host);
});
function initHost(host) {
forEachElement('.place-guest', function(button) {
button.addEventListener('click', function(event) {
var guest_id = document.getElementById('guest_id').value;
if (guest_id) {
var guest = document.getElementById('guest-' + guest_id);
var form = document.getElementById('hosts');
var data = new FormData(form);
host.classList.add('requesting');
if (guest.dataset.affectedHosts) {
data.append('affected-hosts', guest.dataset.affectedHosts);
forEach(guest.dataset.affectedHosts.split(','), function(host_id) {
h = document.getElementById('host-' + host_id);
if (h) {
h.classList.add('requesting');
}
});
}
data.append('button', button.value);
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = JSON.parse(request.responseText);
for (var host_id in response.hosts) {
host_element = document.getElementById('host-' + host_id);
widget = response.hosts[host_id];
host_element.className = widget.class;
host_element.querySelector('.guests').innerHTML = widget.html;
initHost(host_element);
host_element.classList.remove('requesting');
}
for (var guest_id in response.affected_hosts) {
guest_element = document.getElementById('guest-' + guest_id);
if (guest_element) {
guest_element.setAttribute('data-affected-hosts', response.affected_hosts[guest_id].join(','));
}
}
}
}
}
request.open('POST', form.getAttribute('action'), true);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
request.send(data);
}
});
}, host);
}
forEachElement('.on-top-close', function(button) {
button.addEventListener('click', closeOnTop);
});
})();

119
app/assets/javascripts/main.js

@ -12,7 +12,10 @@
);
return false;
};
Array.prototype.forEach.call(document.querySelectorAll('.number-field,.email-field,.text-field'), function(field) {
window.forEach = function(a, f) { Array.prototype.forEach.call(a, f) };
window.forEachElement = function(s, f, p) { forEach((p || document).querySelectorAll(s), f) };
forEachElement('.number-field,.email-field,.text-field', function(field) {
var input = field.querySelector('input');
var positionLabel = function(input) {
field.classList[input.value ? 'remove' : 'add']('empty');
@ -29,53 +32,74 @@
field.classList.add('focused');
});
});
var body = document.querySelector('body');
var primaryContent = document.getElementById('primary-content');
var overlay = document.getElementById('content-overlay');
primaryContent.addEventListener('keydown', function(event) {
if (body.classList.contains('has-overlay')) {
event.stopPropagation();
return false;
if (overlay) {
var body = document.querySelector('body');
var primaryContent = document.getElementById('primary-content');
primaryContent.addEventListener('keydown', function(event) {
if (body.classList.contains('has-overlay')) {
event.stopPropagation();
return false;
}
});
document.addEventListener('focus', function(event) {
if (overlay.querySelector('.dlg.open') && !overlay.querySelector('.dlg.open :focus')) {
overlay.querySelector('.dlg.open').focus();
}
}, true);
function openDlg(dlg, link) {
body.setAttribute('style', 'width: ' + body.clientWidth + 'px');
dlg.querySelector('.message').innerHTML = decodeURI(link.dataset.confirmation);
dlg.querySelector('.confirm').addEventListener('click', function(event) {
event.preventDefault();
if (link.tagName == 'BUTTON') {
var form = link.parentElement
while (form && form.tagName != 'FORM') {
var form = form.parentElement
}
if (form) {
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'button';
input.value = link.value;
form.appendChild(input);
form.submit();
}
} else {
window.location.href = link.getAttribute('href');
}
});
primaryContent.setAttribute('aria-hidden', 'true');
document.getElementById('overlay').onclick =
dlg.querySelector('.delete').onclick = function() { closeDlg(dlg); };
body.classList.add('has-overlay');
dlg.removeAttribute('aria-hidden');
dlg.setAttribute('role', 'alertdialog');
dlg.setAttribute('tabindex', '0');
dlg.focus();
setTimeout(function() { dlg.classList.add('open'); }, 100);
}
});
document.addEventListener('focus', function(event) {
if (overlay.querySelector('.dlg.open') && !overlay.querySelector('.dlg.open :focus')) {
overlay.querySelector('.dlg.open').focus();
function closeDlg(dlg) {
setTimeout(function() {
body.classList.remove('has-overlay');
body.removeAttribute('style');
}, 250);
primaryContent.removeAttribute('aria-hidden');
dlg.setAttribute('aria-hidden', 'true');
dlg.removeAttribute('tabindex');
dlg.classList.remove('open');
dlg.removeAttribute('role');
}
}, true);
function openDlg(dlg, link) {
body.setAttribute('style', 'width: ' + body.clientWidth + 'px');
dlg.querySelector('.message').innerHTML = decodeURI(link.dataset.confirmation);
dlg.querySelector('.confirm').setAttribute('href', link.getAttribute('href'));
primaryContent.setAttribute('aria-hidden', 'true');
document.getElementById('overlay').onclick =
dlg.querySelector('.delete').onclick = function() { closeDlg(dlg); };
body.classList.add('has-overlay');
dlg.removeAttribute('aria-hidden');
dlg.setAttribute('role', 'alertdialog');
dlg.setAttribute('tabindex', '0');
dlg.focus();
setTimeout(function() { dlg.classList.add('open'); }, 100);
}
function closeDlg(dlg) {
setTimeout(function() {
body.classList.remove('has-overlay');
body.removeAttribute('style');
}, 250);
primaryContent.removeAttribute('aria-hidden');
dlg.setAttribute('aria-hidden', 'true');
dlg.removeAttribute('tabindex');
dlg.classList.remove('open');
dlg.removeAttribute('role');
}
var confirmationDlg = document.getElementById('confirmation-dlg');
Array.prototype.forEach.call(document.querySelectorAll('a[data-confirmation]'), function(link) {
link.addEventListener('click', function(event) {
event.preventDefault();
openDlg(confirmationDlg, link);
return false;
var confirmationDlg = document.getElementById('confirmation-dlg');
forEachElement('[data-confirmation]', function(link) {
link.addEventListener('click', function(event) {
event.preventDefault();
openDlg(confirmationDlg, link);
return false;
});
});
});
}
var errorField = document.querySelector('.input-field.has-error input, .input-field.has-error textarea');
if (errorField) {
@ -85,9 +109,8 @@
var htmlNode = document.documentElement;
document.addEventListener('keydown', function(event) {
if (htmlNode.dataset.input != 'kb' &&
!["input", "textarea", "select", "option"].includes(event.target.nodeName.toLowerCase()) &&
!event.target.attributes.contenteditable) {
console.log()
((!["input", "textarea", "select", "option"].includes(event.target.nodeName.toLowerCase()) &&
!event.target.attributes.contenteditable) || event.key == "Tab")) {
htmlNode.setAttribute('data-input', 'kb');
}
});
@ -97,7 +120,7 @@
htmlNode.setAttribute('data-input', 'mouse');
}
});
Array.prototype.forEach.call(document.querySelectorAll('form.js-xhr'), function(form) {
forEachElement('form.js-xhr', function(form) {
if (form.addEventListener) {
form.addEventListener('submit', function(event) {
event.preventDefault();

585
app/assets/stylesheets/_application.scss

@ -23,6 +23,10 @@ h2 {
font-size: 6vw;
}
h3.subtitle {
font-size: 1.5em;
}
p {
font-size: 4vw;
}
@ -69,13 +73,14 @@ a {
table {
margin-bottom: 2em;
margin-left: 1em;
background-color: #F8F8F8;
width: 100%;
@include default-box-shadow(top, 2, true);
// background-color: #F8F8F8;
// width: 100%;
// @include default-box-shadow(top, 2, true);
th, td {
text-align: left;
padding: 0.25em 0.5em;
border: 0.1em solid #EEE;
&:first-child {
padding-left: 1em;
@ -85,6 +90,10 @@ table {
padding-right: 1em;
}
}
th {
background-color: #F8F8F8;
}
}
button,
@ -132,6 +141,10 @@ button,
&.facebook {
background-color: #3A5795;
}
&.small {
font-size: 0.9em;
}
}
a.button {
@ -214,6 +227,11 @@ textarea, .textarea {
@include _(transition, box-shadow 200ms ease-in-out);
will-change: box-shadow;
&[data-edit-on="click"],
&[data-edit-on="focus"] {
cursor: text;
}
&:hover, &:focus, &:active {
@include _(box-shadow, 0 0 0 0.3em rgba(0,0,0,0.05));
}
@ -366,6 +384,12 @@ input {
margin-right: 0;
}
}
&.small select,
&.small input {
font-size: 1em;
@include font-family(secondary)
}
}
.input-field.other-field label {
@ -416,6 +440,8 @@ input {
.input-field-help {
margin-bottom: 1em;
margin-left: 1em;
line-height: 1.3333em;
font-size: 1.25em;
}
.check-box-field,
@ -590,13 +616,13 @@ input {
}
}
.requesting {
opacity: 0.5;
-webkit-filter: blur(5px);
}
form {
@include _(transition, 'opacity 250ms ease-in-out, filter 250ms ease-in-out, -webkit-filter 250ms ease-in-out');
&.requesting {
opacity: 0.5;
-webkit-filter: blur(5px);
}
&.composition {
textarea {
@ -619,6 +645,28 @@ form {
}
}
#main .columns th form {
display: inline;
vertical-align: super;
margin: 0 0 0 0.5em;
button {
float: right;
}
}
#main .columns th.form {
display: none;
}
#main .columns td.form {
border: 0;
form {
margin: 0;
}
}
fieldset {
margin: 0;
padding: 0;
@ -654,6 +702,27 @@ fieldset {
}
}
.flex-inputs {
@include _-(display, flex);
@include _(align-items, flex-end);
@include _(flex-wrap, wrap);
@include _(justify-content, flex-end);
margin-bottom: 2em;
.input-field {
margin: 0 0.5em;
}
.stretch-item {
@include _(flex, 1);
@include _(flex-basis, 100%);
select {
width: 100%;
}
}
}
.actions {
text-align: center;
margin: 0 1em;
@ -682,6 +751,16 @@ fieldset {
}
}
&.fill {
@include _-(display, flex);
@include _(flex-wrap, wrap);
> button, > .button {
flex: 1;
margin-bottom: 0;
}
}
.conferences-view_workshop & {
margin-bottom: 5em;
}
@ -691,6 +770,7 @@ fieldset {
@include _(flex-wrap, wrap);
@include _(flex-direction, row-reverse);
margin: 0;
clear: both;
button, .button {
margin-bottom: 1em;
@ -698,6 +778,27 @@ fieldset {
}
}
.test-preview {
padding: 0 1em;
border: 0.1em solid #CCC;
background-color: #F8F8F8;
h4 {
border-bottom: 0.1rem solid #CCC;
padding: 1em 0 0.75em;
font-size: 1.5em;
margin: 0 0 1em 0;
}
h5 {
font-size: 1.25em;
}
h6, p {
font-size: 1.125em;
}
}
ul.warnings {
list-style: none;
padding: 0;
@ -871,17 +972,16 @@ ul.warnings li,
}
}
#registration-steps {
.flow-steps {
ul {
display: block;
position: relative;
list-style: none;
padding: 0;
margin-top: -1em;
overflow: hidden;
//overflow: hidden;
text-align: center;
@include default-box-shadow(top, 2);
@include _(border-radius, 0.15em);
@include clearfix;
}
@ -897,38 +997,16 @@ ul.warnings li,
outline: 0;
cursor: default;
@include _(text-stroke, 1px rgba(0, 0, 0, 0.25));
@include after {
content: '';
position: absolute;
z-index: 1;
top: 2.25em;
left: 0;
right: 0;
width: 1.25em;
height: 1.25em;
margin: auto;
border: 0 solid;
border-width: 0.1em 0.1em 0 0;
background-color: inherit;
@include _(transform, rotate(135deg));
@include _(transition, 'transform 200ms ease-in-out, background-color 200ms ease-in-out');
@include _(box-shadow, 0.2em -0.4em 0.8em -0.4em #000);
}
&.enabled {
background-color: $colour-5;
}
&.current {
background-color: lighten(desaturate($colour-5, 33%), 15%);
&:last-child {
@include _(border-radius, 0 0 0.15em 0.15em);
}
&:last-child {
padding-right: 1.5em;
&.enabled {
background-color: $colour-1;
@include after {
display: none;
&.current {
background-color: lighten(desaturate($colour-1, 33%), 15%);
}
}
}
@ -946,9 +1024,285 @@ ul.warnings li,
left: 0;
}
@include after {
border-bottom: 0 solid rgba(0,0,0,0.25);
}
@include after {
border-bottom: 0.2em solid rgba(0,0,0,0.25);
}
}
#registration-steps {
li {
&:first-child {
@include _(border-radius, 0.15em 0.15em 0 0);
}
&:last-child {
@include _(border-radius, 0);
}
&.enabled {
background-color: $colour-5;
&.current {
background-color: lighten(desaturate($colour-5, 33%), 15%);
//text-decoration: underline;
}
}
@include after {
content: '';
position: absolute;
z-index: 1;
top: 2.25em;
left: 0;
right: 0;
width: 1.25em;
height: 1.25em;
margin: auto;
border: 0 solid;
border-width: 0.1em 0.1em 0 0;
background-color: inherit;
@include _(transform, rotate(135deg));
@include _(transition, 'transform 200ms ease-in-out, background-color 200ms ease-in-out');
@include _(box-shadow, 0.2em -0.4em 0.8em -0.4em #000);
}
}
}
}
#main article #registration-admin-menu {
margin: 1em 0 0;
padding: 0;
list-style: none;
border: 0.1em solid #EEE;
background-color: #F8F8F8;
a {
display: block;
padding: 0.5em 0.75em;
@include font-family(secondary);
border-bottom: 0.1em solid #CCC;
@include after {
display: none;
}
&:hover {
background-color: #EEE;
}
}
li {
margin: 0;
&:last-child a {
border: 0;
}
&.current {
a {
color: $white;
background-color: $colour-5;
}
}
}
}
.admin-blocks {
@include _-(display, inline-flex);
@include _(flex-wrap, wrap);
@include _(align-items, flex-start);
@include _(justify-content, flex-start);
list-style: none;
padding: 0;
> li {
max-width: 25em;
border: 0.1rem solid #EEE;
padding: 1em;
margin: 0.25em;
@include _(flex, 1);
background-color: #F8F8F8;
@include default-box-shadow(top, 2);
}
.actions {
margin: 0 auto;
}
.title {
margin: 0 0 1em;
padding: 0 0 0.5em;
border-bottom: 0.1rem solid #EEE;
}
.details {
display: table;
width: 100%;
}
.data-set {
display: table-row;
}
.data-set-key, .data-set-value {
display: table-cell;
padding: 0.25em 0.5em;
vertical-align: top;
border-bottom: 0.1rem solid #EEE;
}
.data-set:last-child {
.data-set-key, .data-set-value {
border: 0;
}
}
.space, .address {
.data-set-key, .data-set-value {
white-space: nowrap;
}
}
.amenities {
list-style: none;
padding: 0;
> li {
font-weight: bold;
white-space: nowrap;
display: inline-block;
padding: 0 0.5em;
line-height: 1.5em;
font-size: 0.8em;
border: 0.1rem solid #CCC;
background-color: #EEE;
@include _(border-radius, 0.125rem);
}
}
}
#admin-housing {
#hosts {
background-color: $white;
ul {
list-style: none;
padding: 0;
}
.host {
padding: 0.5em;
border: 0.1em solid #EEE;
background-color: #F8F8F8;
&.status-good {
background-color: rgba($colour-5, 0.1);
}
&.status-warning {
background-color: rgba($colour-3, 0.1);
}
&.status-error {
background-color: rgba($colour-2, 0.1);
}
}
h4 {
margin: 0 0.5em 0 0;
float: left;
}
h5 {
margin: 1em 0 0;
}
.email {
color: #888;
@include before {
content: '(';
}
@include after {
content: ')';
}
}
.guests {
clear: left;
@include _-(display, flex);
}
.space {
@include _(flex, 1);
}
.place-guest {
background-color: $colour-5;
&.booked {
background-color: $colour-4;
}
&.unwanted {
background-color: #888;
}
&.overbooked {
background-color: $colour-2;
}
}
.warning, .error {
display: inline-block;
font-style: italic;
padding: 0 0.5em;
margin-left: 0.5em;
border: 0.1em solid rgba($black, 0.25);
@include _(border-radius, 0.125em);
@include _(transform, skewX(-15deg));
@include _(transform-origin, 0 100%);
@include _(animation, bend ease-in-out 500ms infinite alternate both);
}
.warning {
background-color: lighten($colour-3, 25%);
}
.error {
background-color: lighten($colour-2, 25%);
}
}
#guests {
.guests {
@include _-(display, flex);
@include _(align-items, flex-start);
@include _(flex-wrap, wrap);
list-style: none;
padding: 0;
}
.guest {
flex: 1;
margin: 0.5em;
border: 0.1rem solid #EEE;
background-color: #F8F8F8;
padding: 0.5em;
}
h4 {
margin: 0 0 0.5em;
}
.set-host {
width: 100%;
}
}
}
@ -1190,6 +1544,10 @@ $header-tilt: 8deg;
font-size: 1.5em;
}
body.error-locale-not-available & {
background-color: $colour-5;
}
body.error-500 & {
background-position: 50% 50%;
background-color: $colour-2;
@ -2311,7 +2669,7 @@ html[data-lingua-franca-example="html"] {
font-family: inherit;
font-size: 1.5em;
padding: 0 0.5em;
border: 0.1em solid #333;
border: 0.1rem solid #CCC;
cursor: pointer;
@include default-box-shadow(top, 1.5, false);
}
@ -2332,6 +2690,61 @@ html[data-lingua-franca-example="html"] {
}
}
.on-top-only, .on-top-controls {
display: none !important;
}
html[data-ontop] {
body {
overflow: hidden;
}
.on-top-target {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 1em;
margin: 0 !important;
z-index: 100;
overflow: auto;
}
.on-top-control {
position: fixed;
right: 0;
bottom: 0;
left: 0;
z-index: 101;
margin: 0 !important;
padding: 1em;
background-color: #F8F8F8;
@include default-box-shadow(bottom, 2);
}
.on-top-controls {
overflow: auto;
.on-top-close {
float: right;
background-color: $colour-4;
}
}
.on-top-only, .on-top-controls {
display: inherit !important;
&.space {
display: block !important;
}
}
.not-on-top {
display: none !important;
}
}
@include breakpoint(medium) {
:focus,
input[type="submit"]:focus,
@ -2386,10 +2799,8 @@ html[data-lingua-franca-example="html"] {
}
}
.number-field,
.email-field,
.telephone-field,
.text-field {
.input-field {
&.big select,
&.big input {
font-size: 2em;
}
@ -2416,6 +2827,13 @@ html[data-lingua-franca-example="html"] {
}
}
.flex-inputs {
.stretch-item {
@include _(flex, 1);
@include _(flex-basis, auto);
}
}
#main-nav {
.logo {
margin-top: 0.25em;
@ -2573,32 +2991,68 @@ html[data-lingua-franca-example="html"] {
}
}
#registration-steps {
.flow-steps {
#registration-steps {
li {
display: inline-block;
text-align: center;
float: left;
@include after {
content: '';
top: 1.125em;
left: auto;
right: -0.25em;
@include _(transform, rotate(45deg));
}
/*&.enabled:hover,
&.enabled:hover ~ li {
@include after {
@include _(transform, rotate(-135deg));
background-color: transparent;
}
}*/
&:first-child {
@include _(border-radius, 0.15em 0 0 0.15em);
}
&:last-child {
@include _(border-radius, 0);
}
}
}
#post-registration-steps {
margin-bottom: -2em;
li {
&:first-child {
@include _(border-radius, 0 0.15em 0 0);
}
&:last-child {
@include _(border-radius, 0 0 0.15em 0.15em);
}
}
}
ul {
display: inline-block;
text-align: left;
margin-top: -4em;
vertical-align: top;
}
li {
display: inline-block;
float: left;
@include after {
content: '';
top: 1.125em;
left: auto;
right: -0.25em;
@include _(transform, rotate(45deg));
}
text-align: center;
}
}
&.enabled:hover,
&.enabled:hover ~ li {
@include after {
@include _(transform, rotate(-135deg));
background-color: transparent;
}
}
#registration-admin-menu {
a {
margin: 0;
}
}
@ -2741,6 +3195,13 @@ html[data-lingua-franca-example="html"] {
border: 0.1em solid;
}
}
.admin-blocks {
> li {
@include _(flex, none);
min-width: 12em;
}
}
}
@include breakpoint(large) {

12
app/assets/stylesheets/user-mailer.scss

@ -78,6 +78,18 @@ p, blockquote {
line-height: 1.3333em;
}
h1 {
font-size: 2.5em;
line-height: 1.25em;
padding-bottom: 1em;
}
h2 {
font-size: 1.8em;
line-height: 1.25em;
padding-bottom: 1em;
}
blockquote {
font-style: italic;
margin-bottom: 2em;

39
app/controllers/application_controller.rb

@ -28,6 +28,9 @@ class ApplicationController < LinguaFrancaApplicationController
# add the translations stylesheet if translating
@stylesheets << params[:controller] if params[:controller] == 'translations'
@_inline_scripts ||= []
@_inline_scripts << Rails.application.assets.find_asset('main.js').to_s
ActionMailer::Base.default_url_options = {:host => "#{request.protocol}#{request.host_with_port}"}
if request.post? && params[:action] == 'do_confirm'
@ -161,6 +164,20 @@ class ApplicationController < LinguaFrancaApplicationController
end
end
def locale_not_enabled!(locale = nil)
locale_not_available!(locale)
end
def locale_not_available!(locale = nil)
# set_default_locale
params[:_original_action] = params[:action]
params[:action] = 'error-locale-not-available'
@page_title = 'page_titles.404.Locale_Not_Available'
@main_title_vars = { vars: { language: view_context.language(locale) } }
@main_title = 'error.locale_not_available.title'
render 'application/locale_not_available', status: 404
end
rescue_from StandardError do |exception|
# log the error
logger.info exception.to_s
@ -191,7 +208,7 @@ class ApplicationController < LinguaFrancaApplicationController
user = User.find_by_email(user)
# if the user doesn't exist, just show them a 403
do_403 unless user
do_403 unless user.present?
end
expiry ||= (Time.now + 12.hours)
session[:confirm_uid] = user.id
@ -292,10 +309,12 @@ class ApplicationController < LinguaFrancaApplicationController
translator = User.find(translator_id)
mailer = "#{object.class.table_name.singularize}_translated"
object.get_translators(data, locale).each do |id, user|
if user.id != current_user.id && user.id != translator_id
UserMailer.send_mail mailer do
{ :args => [object, data, locale, user, translator] }
if object.respond_to?(:get_translators)
object.get_translators(data, locale).each do |id, user|
if user.id != current_user.id && user.id != translator_id
UserMailer.send_mail mailer do
{ :args => [object, data, locale, user, translator] }
end
end
end
end
@ -304,10 +323,12 @@ class ApplicationController < LinguaFrancaApplicationController
def on_translatable_content_change(object, data)
mailer = "#{object.class.table_name.singularize}_original_content_changed"
object.get_translators(data).each do |id, user|
if user.id != current_user.id
UserMailer.send_mail mailer do
{ :args => [object, data, user, current_user] }
if object.respond_to?(:get_translators)
object.get_translators(data).each do |id, user|
if user.id != current_user.id
UserMailer.send_mail mailer do
{ :args => [object, data, user, current_user] }
end
end
end
end

306
app/controllers/conferences_controller.rb

@ -535,6 +535,8 @@ class ConferencesController < ApplicationController
steps = registration_steps
return do_404 unless steps.present?
@register_template = :administration if params[:admin_step].present?
@errors = {}
@warnings = []
@ -588,7 +590,7 @@ class ConferencesController < ApplicationController
floor_space: params[:floor_space],
tent_space: params[:tent_space],
},
considerations: params[:considerations].keys,
considerations: (params[:considerations] || {}).keys,
availability: [ params[:first_day], params[:last_day] ],
notes: params[:notes]
}
@ -623,9 +625,17 @@ class ConferencesController < ApplicationController
@register_template ||= (params[:step] || current_step).to_sym
return redirect_to register_path(@this_conference.slug) if
logged_in? && @register_template != current_step &&
!@registration.steps_completed.include?(@register_template.to_s)
if logged_in?
# if we're logged in
if !steps.include?(@register_template)
# and we are not viewing a valid step
return redirect_to register_path(@this_conference.slug)
elsif @register_template != current_step && !registration_complete? && !@registration.steps_completed.include?(@register_template.to_s)
# or the step hasn't been reached, registration is not yet complete, and we're not viewing the latest incomplete step
return redirect_to register_path(@this_conference.slug)
end
# then we'll redirect to the current registration step
end
# process data from the last view
# case (params[:button] || '').to_sym
@ -782,12 +792,281 @@ class ConferencesController < ApplicationController
@hosting_data['considerations'] ||= Array.new
when :policy
@page_title = 'articles.conference_registration.headings.Policy_Agreement'
when :administration
@admin_step = params[:admin_step] || 'edit'
return do_404 unless view_context.valid_admin_steps.include?(@admin_step.to_sym)
@page_title = 'articles.conference_registration.headings.Administration'
case @admin_step.to_sym
when :housing
# do a full analysis
analyze_housing
when :locations
@locations = EventLocation.where(:conference_id => @this_conference.id)
when :events
@event = Event.new(locale: I18n.locale)
@events = Event.where(:conference_id => @this_conference.id)
@day = nil
@time = nil
@length = 1.5
end
when :done
@amount = ((@registration.registration_fees_paid || 0) * 100).to_i.to_s.gsub(/^(.*)(\d\d)$/, '\1.\2')
end
end
def get_housing_data
@hosts = {}
@guests = {}
ConferenceRegistration.where(:conference_id => @this_conference.id).each do | registration |
if registration.can_provide_housing
@hosts[registration.id] = registration
else
@guests[registration.id] = registration
end
end
end
def analyze_housing
get_housing_data unless @hosts.present? && @guests.present?
@housing_data = {}
@hosts_affected_by_guests = {}
@hosts.each do | id, host |
@hosts[id].housing_data ||= {}
@housing_data[id] = { guests: {}, space: {} }
@hosts[id].housing_data['space'] ||= {}
@hosts[id].housing_data['space'].each do | s, size |
size = (size || 0).to_i
@housing_data[id][:guests][s.to_sym] = {}
@housing_data[id][:space][s.to_sym] = size
end
end
@guests.each do | guest_id, guest |
data = guest.housing_data || {}
@hosts_affected_by_guests[guest_id] ||= []
if data['host']
host_id = (data['host'].present? ? data['host'].to_i : nil)
host = host_id.present? ? @hosts[host_id] : nil
# make sure the host was found and that they are still accepting guests
if host.present? && host.can_provide_housing
@hosts_affected_by_guests[guest_id] << host_id
space = (data['space'] || :bed).to_sym
@housing_data[host_id] ||= {}
host_data = host.housing_data
unless @housing_data[host_id][:guests][space].present?
@housing_data[host_id][:guests][space] ||= {}
@housing_data[host_id][:space][space] ||= 0
end
@housing_data[host_id][:guests][space][guest_id] = { guest: guest }
# make sure the host isn't overbooked
space_available = ((host_data['space'] || {})[space.to_s] || 0).to_i
if @housing_data[host_id][:guests][space].size > space_available
@housing_data[host_id][:warnings] ||= {}
@housing_data[host_id][:warnings][:space] ||= {}
@housing_data[host_id][:warnings][:space][space] ||= []
@housing_data[host_id][:warnings][:space][space] << :overbooked
end
companions = data['companions'] || []
companions.each do | companion |
user = User.find_by_email(companion)
if user.present?
reg = ConferenceRegistration.find_by(
:user_id => user.id,
:conference_id => @this_conference.id
)
housing_data = reg.housing_data || {}
companion_host = housing_data['host'].present? ? housing_data['host'].to_i : nil
if companion_host.blank?
@hosts_affected_by_guests[guest_id] << companion_host
if companion_host != host_id
# set this as an error if the guest has selected only one other to stay with, but if they have requested to stay with more, make this only a warning
status = companions.size > 1 ? :warnings : :errors
@housing_data[host_id][:guests][guest][status] ||= {}
@housing_data[host_id][:guests][guest][status][:companions] ||= []
@housing_data[host_id][:guests][guest][status][:companions] << reg.id
end
end
end
end
else
# make sure the housing data is empty if the host wasn't found, just in case something happened to the host
@guests[guest_id].housing_data ||= {}
@guests[guest_id].housing_data['host'] = nil
@guests[guest_id].housing_data['space'] = nil
end
end
end
return @hosts_affected_by_guests
end
def admin_update
set_conference
set_conference_registration
return do_403 unless @this_conference.host? current_user
# set the page title in case we render instead of redirecting
@page_title = 'articles.conference_registration.headings.Administration'
@register_template = :administration
@admin_step = params[:admin_step]
case params[:admin_step]
when 'edit'
@this_conference.info = LinguaFranca::ActiveRecord::UntranslatedValue.new(params[:info]) unless @this_conference.info! == params[:info]
params[:info_translations].each do | locale, value |
@this_conference.set_column_for_locale(:info, locale, value, current_user.id) unless value = @this_conference._info(locale)
end
@this_conference.save
return redirect_to register_step_path(@this_conference.slug, :administration)
when 'housing'
space = params[:button].split(':')[0]
host_id = params[:button].split(':')[1].to_i
guest_id = params[:guest_id].to_i
get_housing_data
# modify the guest data
@guests[guest_id].housing_data ||= {}
@guests[guest_id].housing_data['space'] = space
@guests[guest_id].housing_data['host'] = host_id
@guests[guest_id].save!
if request.xhr?
analyze_housing
# get the hosts that need updating
affected_hosts = {}
affected_hosts[host_id] = @hosts[host_id]
if params['affected-hosts'].present?
params['affected-hosts'].split(',').each do | id |
affected_hosts[id.to_i] = @hosts[id.to_i]
end
end
@hosts_affected_by_guests[guest_id].each do | id |
affected_hosts[id] ||= @hosts[id]
end
json = { hosts: {}, affected_hosts: @hosts_affected_by_guests }
puts @hosts_affected_by_guests[guest_id].to_json.to_s
affected_hosts.each do | id, host |
json[:hosts][id] = view_context.host_guests_widget(host)
end
return render json: json
end
return redirect_to administration_step_path(@this_conference.slug, :housing)
when 'broadcast'
@subject = params[:subject]
@body = params[:body]
@register_template = :administration
if params[:button] == 'send'
return redirect_to administration_step_path(@this_conference.slug, :broadcast_sent)
elsif params[:button] == 'preview'
@broadcast_step = :preview
elsif params[:button] == 'test'
@broadcast_step = :test
UserMailer.broadcast(
"#{request.protocol}#{request.host_with_port}",
@subject,
@body,
current_user,
@this_conference).deliver_now
end
return render 'conferences/register'
when 'locations'
case params[:button]
when 'edit'
@location = EventLocation.find_by! id: params[:id].to_i, conference_id: @this_conference.id
return render 'conferences/register'
when 'save'
location = EventLocation.find_by! id: params[:id].to_i, conference_id: @this_conference.id
location.title = params[:title]
location.address = params[:address]
location.amenities = (params[:needs] || {}).keys.to_json
location.space = params[:space]
location.save!
return redirect_to administration_step_path(@this_conference.slug, :locations)
when 'cancel'
return redirect_to administration_step_path(@this_conference.slug, :locations)
when 'delete'
location = EventLocation.find_by! id: params[:id].to_i, conference_id: @this_conference.id
location.destroy
return redirect_to administration_step_path(@this_conference.slug, :locations)
when 'create'
EventLocation.create(
conference_id: @this_conference.id,
title: params[:title],
address: params[:address],
amenities: (params[:needs] || {}).keys.to_json,
space: params[:space]
)
return redirect_to administration_step_path(@this_conference.slug, :locations)
end
when 'meals'
case params[:button]
when 'add_meal'
@this_conference.meals ||= {}
@this_conference.meals[(Date.parse(params[:day]) + params[:time].to_f.hours).to_time.to_i] = {
title: params[:title],
info: params[:info],
location: params[:event_location],
day: params[:day],
time: params[:time]
}
@this_conference.save!
return redirect_to administration_step_path(@this_conference.slug, :meals)
when 'delete'
@this_conference.meals ||= {}
@this_conference.meals.delete params[:meal]
@this_conference.save!
return redirect_to administration_step_path(@this_conference.slug, :meals)
end
when 'events'
case params[:button]
when 'edit'
@event = Event.find_by!(conference_id: @this_conference.id, id: params[:id])
@day = @event.start_time.midnight
@time = view_context.hour_span(@day, @event.start_time)
@length = view_context.hour_span(@event.start_time, @event.end_time)
return render 'conferences/register'
when 'save'
if params[:id].present?
event = Event.find_by!(conference_id: @this_conference.id, id: params[:id])
else
event = Event.new(conference_id: @this_conference.id, locale: I18n.locale)
end
# save title and info
event.title = LinguaFranca::ActiveRecord::UntranslatedValue.new(params[:title]) unless event.title! == params[:title]
event.info = LinguaFranca::ActiveRecord::UntranslatedValue.new(params[:info]) unless event.info! == params[:info]
# save schedule data
event.event_location_id = params[:event_location]
event.start_time = Date.parse(params[:day]) + params[:time].to_f.hours
event.end_time = event.start_time + params[:time_span].to_f.hours
# save translations
(params[:info_translations] || {}).each do | locale, value |
event.set_column_for_locale(:title, locale, value, current_user.id) unless value = event._title(locale)
event.set_column_for_locale(:info, locale, value, current_user.id) unless value = event._info(locale)
end
event.save
return redirect_to administration_step_path(@this_conference.slug, :events)
end
end
do_404
end
def registrations
registrations = ConferenceRegistration.where(:conference_id => @conference.id)
@registrations = registrations
@ -1219,7 +1498,7 @@ class ConferencesController < ApplicationController
set_conference
return do_404 unless @this_conference.workshop_schedule_published || @this_conference.host?(current_user)
@events = Event.where(:conference_id => @this_conference.id)
@events = Event.where(:conference_id => @this_conference.id).order(start_time: :asc)
@locations = EventLocation.where(:conference_id => @this_conference.id)
render 'schedule/show'
@ -1491,10 +1770,21 @@ class ConferencesController < ApplicationController
status = conference.registration_status
return [] unless status == :pre || status == :open
steps = [:policy, :contact_info, :questions, :hosting, :payment, :workshops]
steps = [
:policy,
:contact_info,
:questions,
:hosting,
:payment,
:workshops,
:administration
]
steps -= [:questions, :payment] unless status == :open
steps -= [:hosting] unless @registration.present? && view_context.same_city?(@registration.city, @conference.location)
steps -= [:administration] unless @registration.present? && @conference.host?(current_user)
return steps
end
@ -1507,6 +1797,7 @@ class ConferencesController < ApplicationController
def registration_complete?(registration = @registration)
completed_steps = registration.steps_completed || []
required_steps(registration.conference).each do | step |
return true if step == :workshops
return false unless completed_steps.include?(step.to_s)
end
return true
@ -1519,9 +1810,10 @@ class ConferencesController < ApplicationController
current_steps = []
disable_steps = false
completed_steps = registration.steps_completed || []
registration_complete = registration_complete?(registration)
steps.each do | step |
# disable the step if we've already found an incomplete step
enabled = !disable_steps
enabled = !disable_steps || registration_complete
# record whether or not we've found an incomplete step
disable_steps ||= !completed_steps.include?(step.to_s)

273
app/helpers/application_helper.rb

@ -100,7 +100,7 @@ module ApplicationHelper
def add_stylesheet(sheet)
@stylesheets ||= []
@stylesheets << sheet
@stylesheets << sheet unless @stylesheets.include?(sheet)
end
def stylesheets
@ -119,7 +119,8 @@ module ApplicationHelper
def add_inline_script(script)
@_inline_scripts ||= []
@_inline_scripts << Rails.application.assets.find_asset("#{script.to_s}.js").to_s
script = Rails.application.assets.find_asset("#{script.to_s}.js").to_s
@_inline_scripts << script unless @_inline_scripts.include?(script)
end
def inline_scripts
@ -644,8 +645,22 @@ module ApplicationHelper
link_to "<span class=\"title\">#{title}</span>".html_safe, link, :class => classes
end
def language(locale, original_language = false)
_("languages.#{locale}", locale: original_language ? locale : nil)
end
def date(date, format = :long)
I18n.l(date, :format => format) # default, long, short
I18n.l(date.is_a?(String) ? Date.parse(date) : date, :format => format)
end
def time(time, format = :short)
if time.is_a?(String)
time = Date.parse(time)
elsif time.is_a?(Float) || time.is_a?(Integer)
time = DateTime.now.midnight + time.hours
end
I18n.l(time, :format => format)
end
def date_span(date1, date2)
@ -660,6 +675,22 @@ module ApplicationHelper
_('date.date_span', vars: {:date_1 => d1, :date_2 => d2})
end
def time_length(length)
hours = length.to_i
minutes = ((length - hours) * 60).to_i
hours = hours > 0 ? (I18n.t 'datetime.distance_in_words.x_hours', count: hours) : nil
minutes = minutes > 0 ? (I18n.t 'datetime.distance_in_words.x_minutes', count: minutes) : nil
return hours.present? ? (minutes.present? ? (I18n.t 'datetime.distance_in_words.x_and_y', x: hours, y: minutes) : hours) : minutes
end
def hour_span(time1, time2)
(time2 - time1) / 3600
end
def hours(time1, time2)
time_length hour_span(time1, time2)
end
def generate_confirmation(user, url, expiry = nil)
ApplicationController::generate_confirmation(user, url, expiry)
end
@ -674,7 +705,18 @@ module ApplicationHelper
_!((p * 10000).to_i.to_s.gsub(/^(.*)(\d\d)$/, '\1.\2%'))
end
def conference_housing_options(conference = nil)
def data_set(header_type, header_key, attributes = {}, &block)
attributes[:class] = attributes[:class].split(' ') if attributes[:class].is_a?(String)
attributes[:class] = [attributes[:class].to_s] if attributes[:class].is_a?(Symbol)
attributes[:class] ||= []
attributes[:class] << 'data-set'
content_tag(:div, attributes) do
content_tag(header_type, _(header_key), class: 'data-set-key') +
content_tag(:div, class: 'data-set-value', &block)
end
end
def conference_days_options(conference = nil)
conference ||= @this_conference || @conference
return [] unless conference
@ -690,22 +732,135 @@ module ApplicationHelper
return dates
end
def conference_housing_options_list(period, conference = nil)
def conference_days_options_list(period, conference = nil, format = nil)
conference ||= @this_conference || @conference
return [] unless conference
days = []
conference_housing_options(conference).each do |day|
conference_days_options(conference).each do |day|
belongs_to_periods = []
belongs_to_periods << :before if day <= conference.start_date
belongs_to_periods << :after if day >= conference.end_date
belongs_to_periods << :during if day >= conference.start_date && day <= conference.end_date
days << [date(day.to_date, :span_same_year_date_1), day] if belongs_to_periods.include?(period)
days << [date(day.to_date, format || :span_same_year_date_1), day] if belongs_to_periods.include?(period)
end
return days
end
def day_select(value = nil, args = {})
selectfield :day, value, conference_days_options_list(:during, nil, args[:format]), args
end
def time_select(value = nil, args = {}, start_time = 8, end_time = 23.5, step = 0.5)
time = start_time
times = []
while time <= end_time
times << [time(DateTime.now.midnight + time.hours), time]
time += step
end
selectfield :time, value, times, args
end
def length_select(value = nil, args = {}, min_length = 0.5, max_length = 6, step = 0.5)
length = min_length
lengths = []
while length <= max_length
lengths << [time_length(length), length]
length += step
end
selectfield :time_span, value, lengths, args
end
def location_select(value = nil, args = {})
locations = []
if @this_conference.event_locations.present?
@this_conference.event_locations.each do | location |
locations << [ location.title, location.id ]
end
end
selectfield :event_location, value, locations, args
end
def location_name(id)
location = EventLocation.find(id)
return '' unless location.present?
return location.title
end
def host_options_list(hosts)
options = [[nil, nil]]
hosts.each do | id, registration |
options << [registration.user.name, id]
end
return options
end
def registration_step_menu
steps = current_registration_steps(@registration)
return '' unless steps.present?
pre_registration_steps = ''
post_registration_steps = ''
post_registration = false
steps.each do | step |
text = _"articles.conference_registration.headings.#{step[:name].to_s}"
h = content_tag :li, class: [step[:enabled] ? :enabled : nil, @register_template == step[:name] ? :current : nil] do
if step[:enabled]
content_tag :div, (link_to text, register_step_path(@this_conference.slug, step[:name])).html_safe, class: :step
else
content_tag :div, text, class: :step
end
end
if step[:name] == :workshops
post_registration = true
end
if post_registration
post_registration_steps += h.html_safe
else
pre_registration_steps += h.html_safe
end
end
html = (
row class: 'flow-steps' do
columns do
(content_tag :ul, id: 'registration-steps' do
pre_registration_steps.html_safe
end).html_safe +
(content_tag :ul, id: 'post-registration-steps' do
post_registration_steps.html_safe
end).html_safe
end
end
)
return html.html_safe
end
def admin_steps
[:edit, :stats, :broadcast, :housing, :locations, :meals, :events, :schedule]
end
def valid_admin_steps
admin_steps + [:broadcast_sent]
end
def admin_menu
steps = ''
admin_steps.each do | step |
steps += content_tag(:li, class: (step.to_s == @admin_step ? :current : nil)) do
link_to _("menu.submenu.admin.#{step.to_s.titlecase}"), step == :edit ?
register_step_path(@this_conference.slug, :administration) :
administration_step_path(@this_conference.slug, step.to_s)
end
end
content_tag :ul, steps.html_safe, id: 'registration-admin-menu'
end
def interest_button(workshop)
interested = workshop.interested?(current_user) ? :remove_interest : :show_interest
id = "#{interested.to_s.gsub('_', '-')}-#{workshop.id}"
@ -713,6 +868,36 @@ module ApplicationHelper
(button_tag interested, :value => :toggle_interest, :class => (workshop.interested?(current_user) ? :delete : :add), aria: { labelledby: id })
end
def host_guests_widget(registration)
html = ''
classes = ['host']
id = registration.id
@housing_data[id][:guests].each do | area, guests |
max_space = @housing_data[id][:space][area] || 0
area_name = (_"forms.labels.generic.#{area}")
status_html = ''
if @housing_data[id][:warnings].present? && @housing_data[id][:warnings][:space].present? && @housing_data[id][:warnings][:space][area].present?
@housing_data[id][:warnings][:space][area].each do | w |
status_html += content_tag(:div, _("warnings.housing.space.#{w.to_s}"), class: 'warning')
end
end
space_html = content_tag(:h5, area_name + _!(" (#{guests.size.to_s}/#{max_space.to_s})") + status_html.html_safe)
guest_items = ''
guests.each do | guest_id, guest |
guest_items += content_tag(:li, guest[:guest].user.name, id: "hosted-guest-#{guest_id}")
end
space_html += content_tag(:ul, guest_items.html_safe)
space_html += button_tag :place_guest, type: :button, value: "#{area}:#{id}", class: [:small, 'place-guest', 'on-top-only', guests.size >= max_space ? (guests.size > max_space ? :overbooked : :booked) : nil, max_space > 0 ? nil : :unwanted]
html += content_tag(:div, space_html, class: [:space, area, max_space > 0 || guests.size > 0 ? nil : 'on-top-only'])
end
classes << 'status-warning' if @housing_data[id][:warnings].present?
classes << 'status-error' if @housing_data[id][:errors].present?
return { html: html.html_safe, class: classes.join(' ') }
end
def link_with_confirmation(link_text, confirmation_text, path, args = {})
@confirmation_dlg ||= true
args[:data] ||= {}
@ -720,6 +905,13 @@ module ApplicationHelper
link_to link_text, path, args
end
def button_with_confirmation(button_name, confirmation_text, args = {})
@confirmation_dlg ||= true
args[:data] ||= {}
args[:data][:confirmation] = CGI::escapeHTML(confirmation_text)
button_tag button_name, args
end
def richtext(text, reduce_headings = 2)
return '' unless text.present?
return _!(text).
@ -731,31 +923,45 @@ module ApplicationHelper
end
def textarea(name, value, options = {})
label_id = "#{name.to_s}-label"
id = name.to_s.gsub('[', '_').gsub(']', '')
label_id = "#{id}-label"
description_id = nil
html = label_tag(name, nil, id: label_id)
if options[:label].present?
html = label_tag(id, nil, id: label_id) do
_(options[:label], :t, vars: options[:vars] || {})
end
else
html = label_tag(id, nil, id: label_id)
end
if options[:help].present?
description_id ||= "#{name.to_s}-desc"
description_id ||= "#{id}-desc"
html += content_tag(:div, _(options[:help], :s, 2), id: description_id, class: 'input-field-help')
end
if options[:warning].present?
description_id ||= "#{name.to_s}-desc"
description_id ||= "#{id}-desc"
html += content_tag(:div, _(options[:warning], :s, 2), id: description_id, class: 'warning-info')
end
html += content_tag(:div, value.present? ? value.html_safe : '',
id: name,
id: id,
class: 'textarea',
data: { name: name },
data: { name: name, 'edit-on': options[:edit_on] || :load },
lang: options[:lang],
aria: { labeledby: label_id, describedby: description_id }
aria: { labeledby: label_id, describedby: description_id },
tabindex: 0
)
html = content_tag(:div, html, class: ['text-area-field', 'input-field']).html_safe
html += _original_content(options[:original_value], options[:original_lang]) if options[:original_value].present?
add_stylesheet :editor
add_inline_script :pen
add_inline_script :markdown
add_inline_script :editor
return html.html_safe
end
@ -766,7 +972,7 @@ module ApplicationHelper
if options[:heading].present?
label_id ||= "#{name.to_s}-label"
html += content_tag(:h3, _(options[:heading], :t), id: label_id)
html += content_tag(:h3, _(options[:heading], :t, vars: options[:vars] || {}), id: label_id)
end
if options[:help].present?
@ -797,27 +1003,50 @@ module ApplicationHelper
def textfield(name, value, options = {})
html = ''
id = name.to_s.gsub('[', '_').gsub(']', '')
description_id = nil
if options[:heading].present?
description_id ||= "#{name.to_s}-desc"
html += content_tag(:h3, _(options[:heading], :t), id: description_id)
description_id ||= "#{id.to_s}-desc"
html += content_tag(:h3, _(options[:heading], :t, vars: options[:vars] || {}), id: description_id)
end
if options[:help].present?
description_id ||= "#{name.to_s}-desc"
html += content_tag(:div, _(options[:help], :s, 2), class: 'input-field-help', id: description_id)
description_id ||= "#{id.to_s}-desc"
html += content_tag(:div, _(options[:help], :s, 2, vars: options[:vars] || {}), class: 'input-field-help', id: description_id)
end
html += show_errors name, value
html += label_tag name
if options[:label].present?
html += label_tag(id) do
_(options[:label], :t, vars: options[:vars] || {})
end
elsif options[:label] != false
html += label_tag id
end
input_options = {
id: id,
required: options[:required],
lang: options[:lang],
min: options[:min],
max: options[:max],
aria: { describedby: description_id }
aria: description_id ? { describedby: description_id } : nil
}
case name
when :address
input_options[:autocomplete] = 'address-line1'
when :name
input_options[:autocomplete] = 'name'
when :location
input_options[:autocomplete] = 'address-level2'
when :email
input_options[:autocomplete] = 'email'
when :phone
input_options[:autocomplete] = 'tel'
end
case options[:type]
when :select
html += select_tag(name, options_for_select(options[:options], value), input_options)
@ -830,6 +1059,8 @@ module ApplicationHelper
"#{(options[:type] || :text).to_s}-field",
'input-field',
options[:big] ? 'big' : nil,
options[:small] ? 'small' : nil,
options[:stretch] ? 'stretch-item' : nil,
(@errors || {})[name].present? ? 'has-error' : nil
])

2
app/models/conference.rb

@ -8,6 +8,7 @@ class Conference < ActiveRecord::Base
has_many :conference_host_organizations, :dependent => :destroy
has_many :organizations, :through => :conference_host_organizations
has_many :event_locations
#has_many :conference_registration_form_fields, :order => 'position ASC', :dependent => :destroy#, :class_name => '::ConferenceRegistrationFormField'
#has_many :registration_form_fields, :through => :conference_registration_form_fields
@ -21,6 +22,7 @@ class Conference < ActiveRecord::Base
end
def host?(user)
return false unless user.present?
organizations.each do |o|
return true if o.host?(user)
end

3
app/models/event.rb

@ -1,5 +1,8 @@
class Event < ActiveRecord::Base
translates :info, :title
belongs_to :conference
belongs_to :event_location
def conference_day
return nil unless start_time.present? && end_time.present?

23
app/models/event_location.rb

@ -1,2 +1,25 @@
require 'geocoder'
require 'geocoder/railtie'
Geocoder::Railtie.insert
class EventLocation < ActiveRecord::Base
belongs_to :conference
geocoded_by :full_address
reverse_geocoded_by :latitude, :longitude, :address => :full_address
after_validation :geocode, if: ->(obj){ obj.address_changed? }
def full_address
l = conference.location
[address, l.city, l.territory, l.country].join(', ')
end
def self.all_spaces
Workshop.all_spaces + [:event_space]
end
def self.all_amenities
Workshop.all_needs
end
end

13
app/models/user.rb

@ -3,17 +3,8 @@ class User < ActiveRecord::Base
config.authentications_class = Authentication
end
#validates :password, presence: true, confirmation: true, length: { minimum: 3 }, unless: ("id?" || "password_confirmation?")
#validates :password_confirmation, presence: true, unless: ("id?" || "password?")
validates :email, uniqueness: true
#validates_presence_of :avatar
#validates_integrity_of :avatar
#validates_processing_of :avatar
#has_secure_password validations: false
mount_uploader :avatar, AvatarUploader
has_many :user_organization_relationships
@ -21,6 +12,10 @@ class User < ActiveRecord::Base
has_many :authentications, :dependent => :destroy
accepts_nested_attributes_for :authentications
before_save do |user|
user.locale = I18n.locale
end
def can_translate?(to_locale = nil, from_locale = nil)
is_translator unless to_locale.present?

8
app/models/workshop.rb

@ -115,6 +115,14 @@ class Workshop < ActiveRecord::Base
[:race_gender, :mechanics, :funding, :organization, :community]
end
def self.all_spaces
[:meeting_room, :workshop, :outdoor_meeting]
end
def self.all_needs
[:sound, :projector, :tools]
end
def get_translators(data, loc = nil)
notify_list = {}
active_facilitators.each do |facilitator|

2
app/views/application/_header.html.haml

@ -15,4 +15,4 @@
=@page_title.present? ? I18n.t(@page_title, @page_title_vars) : I18n.t("page_titles.#{page_group.to_s}.#{page_key.to_s}")
= row do
= columns do
%h1=_(@main_title || "page_titles.#{page_group.to_s}.#{page_key.to_s}")
%h1=_(@main_title || "page_titles.#{page_group.to_s}.#{page_key.to_s}", :t, @main_title_vars)

4
app/views/application/locale_not_available.html.haml

@ -0,0 +1,4 @@
= render :partial => 'application/header', :locals => {:image_file => 'runes.jpg'}
= row do
= columns(medium: 12) do
= paragraph(_'error.locale_not_available.description', :p, @main_title_vars)

7
app/views/conferences/_administration.html.haml

@ -0,0 +1,7 @@
= columns(medium: 12) do
%h2=_(@page_title)
= columns(medium: 3, large: 2) do
= admin_menu
= columns(medium: 9, large: 10) do
%h3.subtitle=_("menu.submenu.admin.#{@admin_step.titlecase}")
%div{id: "admin-#{@admin_step}"}= render "conferences/admin/#{@admin_step}"

2
app/views/conferences/_contact_info.html.haml

@ -5,7 +5,7 @@
= form_tag register_path(@this_conference.slug) do
= textfield :name, @name, required: true, heading: 'articles.conference_registration.headings.name', big: true
= textfield :location, (params[:location] || @registration.city || location(lookup_ip_location)), required: true, heading: 'articles.conference_registration.headings.location'
= checkboxes :languages, [:en, :es, :fr], current_user.languages, 'languages', heading: 'articles.conference_registration.headings.languages'
= checkboxes :languages, [:en, :es, :fr], current_user.languages || [I18n.locale], 'languages', heading: 'articles.conference_registration.headings.languages'
.actions.next-prev
= button_tag (params[:step] == :save ? :save : :next), value: :contact_info
= button_tag :previous, value: :prev_contact_info, class: :subdued, formnovalidate: true

11
app/views/conferences/_hosting.html.haml

@ -1,8 +1,3 @@
- add_stylesheet :editor
- add_inline_script :pen
- add_inline_script :markdown
- add_inline_script :editor
= columns(medium: 12) do
%h2=_(@page_title)
= columns(medium: 12) do
@ -15,10 +10,10 @@
- [:bed_space, :floor_space, :tent_space].each do | space |
= numberfield space, @hosting_data['space'][space.to_s] || 0, min: 0, required: true
= fieldset :hosting_dates, heading: 'articles.conference_registration.headings.host.availability', help: 'articles.conference_registration.paragraphs.host.availability' do
= selectfield :first_day, @hosting_data['availability'][0] || @this_conference.start_date, conference_housing_options_list(:before)
= selectfield :last_day, @hosting_data['availability'][1] || @this_conference.start_date, conference_housing_options_list(:after)
= selectfield :first_day, @hosting_data['availability'][0] || @this_conference.start_date, conference_days_options_list(:before)
= selectfield :last_day, @hosting_data['availability'][1] || @this_conference.start_date, conference_days_options_list(:after)
= checkboxes :considerations, [:vegan, :smoking, :pets, :quiet], @hosting_data['considerations'], 'articles.conference_registration.host.considerations', heading: 'articles.conference_registration.headings.host.considerations', help: 'articles.conference_registration.paragraphs.host.considerations', vertical: true
= textarea :notes, @hosting_data['notes'], heading: 'articles.conference_registration.headings.host.notes', help: 'articles.conference_registration.paragraphs.host.notes'
= textarea :notes, @hosting_data['notes'], heading: 'articles.conference_registration.headings.host.notes', help: 'articles.conference_registration.paragraphs.host.notes', edit_on: :focus
.actions.next-prev
= button_tag (params[:step] == :save ? :save : :next), value: :hosting
= button_tag :previous, value: :prev_contact_info, class: :subdued, formnovalidate: true

19
app/views/conferences/admin/_broadcast.html.haml

@ -0,0 +1,19 @@
= form_tag administration_update_path(@this_conference.slug, :broadcast) do
- if @broadcast_step == :preview || @broadcast_step == :test
= hidden_field_tag :subject, @subject
= hidden_field_tag :body, @body
.test-preview
%h4=@subject
= richtext @body, 4
.actions.right
= button_tag :test, value: :test, class: :secondary if @broadcast_step == :preview
= button_with_confirmation :send, (_'modals.admin.broadcast.confirm', vars: { number: @subscriber_count || 0 }), value: :send, class: :delete if @broadcast_step == :test
= button_tag :edit, value: :edit
- else
= textfield :subject, @subject, required: true, big: true
= textarea :body, @body, heading: 'articles.conference_registration.headings.admin.edit.info', help: 'articles.conference_registration.paragraphs.admin.edit.info', lang: @this_conference.locale, edit_on: :focus
.actions.right
= button_tag :preview, value: :preview
-# I18n.backend.enabled_locales.each do | locale |
-# if locale.to_s != @this_conference.locale.to_s
-#= textarea "info_translations[#{locale.to_s}]", (richtext @this_conference._info(locale)), label: 'translate.pages.Locale_Translation', vars: { language: _("languages.#{locale}") }, lang: locale

1
app/views/conferences/admin/_broadcast_sent.html.haml

@ -0,0 +1 @@
Sent.

7
app/views/conferences/admin/_edit.html.haml

@ -0,0 +1,7 @@
= form_tag administration_update_path(@this_conference.slug, :edit) do
= textarea :info, @this_conference.info!, heading: 'articles.conference_registration.headings.admin.edit.info', help: 'articles.conference_registration.paragraphs.admin.edit.info', lang: @this_conference.locale, edit_on: :focus
- I18n.backend.enabled_locales.each do | locale |
- if locale.to_s != @this_conference.locale.to_s
= textarea "info_translations[#{locale.to_s}]", @this_conference._info(locale), label: 'translate.pages.Locale_Translation', vars: { language: _("languages.#{locale}") }, lang: locale, edit_on: :focus
.actions.right
= button_tag :save, value: :save

36
app/views/conferences/admin/_events.html.haml

@ -0,0 +1,36 @@
- if @events.present?
%ul.events.admin-blocks
- @events.each do | event |
%li
%h4.title=event.title
.details
= data_set(:h5, 'forms.labels.generic.event_location', class: :location) do
=event.event_location.present? ? event.event_location.title : ''
= data_set(:h5, 'forms.labels.generic.day', class: :day) do
= date(event.start_time.to_date, :weekday)
= data_set(:h5, 'forms.labels.generic.time', class: :time) do
= time(event.start_time, :short)
= data_set(:h5, 'forms.labels.generic.time_span', class: 'time-span') do
= hours(event.start_time, event.end_time)
= form_tag administration_update_path(@this_conference.slug, :events), class: [:actions, :fill] do
= hidden_field_tag :id, event.id
= button_with_confirmation :delete, (_'modals.admin.generic.delete.confirm', :p, vars: { title: event.title }), value: :delete, class: [:delete, :small]
= button_tag :edit, value: :edit, class: [:small]
%h4=_"articles.admin.locations.headings.#{@event.id.present? ? 'edit' : 'add'}_event", :t
= form_tag administration_update_path(@this_conference.slug, :events) do
= hidden_field_tag :id, @event.id if @event.id.present?
= textfield :title, @event.title!, required: true, big: true, lang: @event.locale
= textarea :info, @event.info!, heading: 'articles.conference_registration.headings.admin.edit.info', help: 'articles.conference_registration.paragraphs.admin.edit.info', lang: @event.locale, edit_on: :focus
.flex-inputs
= location_select @event.event_location_id, small: true, stretch: true
= day_select @day, small: true, format: :weekday
= time_select @time, small: true
= length_select @length, small: true
- I18n.backend.enabled_locales.each do | locale |
- if locale.to_s != @event.locale.to_s
= textfield "title_translations[#{locale.to_s}]", @event._title(locale), big: true, heading: 'translate.pages.Locale_Translation', vars: { language: _("languages.#{locale}") }, label: 'forms.labels.generic.title', lang: locale
= textarea "info_translations[#{locale.to_s}]", @event._info(locale), lang: locale, label: 'forms.labels.generic.info', edit_on: :focus
.actions.next-prev
= button_tag :save, value: :save
= button_tag :cancel, value: :cancel, class: :subdued, formnovalidate: true if @event.id.present?

26
app/views/conferences/admin/_housing.html.haml

@ -0,0 +1,26 @@
- add_inline_script :housing
= form_tag administration_update_path(@this_conference.slug, :housing), id: :hosts, class: 'on-top-target' do
= hidden_field_tag :guest_id
.on-top-controls
= button_tag :close, type: :button, class: ['on-top-close']
%ul
- @hosts.each do | id, registration |
- if registration.user.present?
- widget_data = host_guests_widget(registration)
%li{id: "host-#{id}", class: widget_data[:class]}
%h4=registration.user.name
.email=registration.user.email
.address=registration.housing_data['address']
.guests=widget_data[:html]
#guests
%h4=_'articles.admin.housing.headings.guests', :t
%ul.guests
- @guests.each do | id, registration |
- if registration.user.present?
%li.guest{id: "guest-#{id}", data: { id: id, 'affected-hosts': @hosts_affected_by_guests[id].join(',') }}
%h4= registration.user.name
.city.on-top-only=registration.city
.email.on-top-only=registration.user.email
= button_tag :set_host, type: :button, class: [:small, 'set-host', 'not-on-top']

35
app/views/conferences/admin/_locations.html.haml

@ -0,0 +1,35 @@
- unless @location.present?
%ul.locations.admin-blocks
- @locations.each do | location |
%li
%h4.title=location.title
.details
= data_set(:h5, 'forms.labels.generic.address', class: :address) do
=location.address
= data_set(:h5, 'articles.workshops.headings.space', class: :space) do
= _"workshop.options.space.#{location.space}"
- amenities = location.amenities.present? ? JSON.parse(location.amenities) : []
- if amenities.present?
= data_set(:h5, 'articles.admin.locations.headings.amenities', class: :amenities) do
%ul.amenities
- amenities.each do | amenity |
%li=_"workshop.options.needs.#{amenity}"
= form_tag administration_update_path(@this_conference.slug, :locations), class: [:actions, :fill] do
= hidden_field_tag :id, location.id
= button_tag :edit, value: :edit, class: :small
= button_with_confirmation :delete, (_'modals.admin.generic.delete.confirm', :p, vars: { title: location.title }), value: :delete, class: [:delete, :small]
%h4=_"articles.admin.locations.headings.#{@location.present? ? 'edit' : 'add'}_location", :t
= form_tag administration_update_path(@this_conference.slug, :locations) do
= hidden_field_tag :id, @location.id if @location.present?
= textfield :title, @location.present? ? @location.title : nil, required: true, big: true
= textfield :address, @location.present? ? @location.address : nil, required: true
= columns(medium: 6) do
= radiobuttons :space, EventLocation.all_spaces, @location.present? ? @location.space : nil, 'workshop.options.space', vertical: true, heading: 'articles.workshops.headings.space'
= columns(medium: 6) do
= checkboxes :needs, EventLocation.all_amenities, @location.present? ? JSON.parse(@location.amenities) : [], 'workshop.options.needs', vertical: true, heading: 'articles.admin.locations.headings.amenities'
.actions.next-prev
- if @location.present?
= button_tag :save, value: :save
= button_tag :cancel, value: :cancel, class: :subdued, formnovalidate: true
- else
= button_tag :create, value: :create

30
app/views/conferences/admin/_meals.html.haml

@ -0,0 +1,30 @@
- if @this_conference.meals.present?
%table.meals
%tr
%th=_'forms.labels.generic.title'
%th=_'forms.labels.generic.info'
%th=_'forms.labels.generic.event_location'
%th=_'forms.labels.generic.day'
%th=_'forms.labels.generic.time'
%th.form
- Hash[@this_conference.meals.map{ |k, v| [k.to_i, v] }].sort.to_h.each do | time, meal |
%tr
%th
=_!(meal['title'] || '')
%td=_!(meal['info'] || '')
%td=_!location_name(meal['location'].to_i)
%td=date(meal['day'], :weekday)
%td=time(meal['time'].to_f)
%td.form
= form_tag administration_update_path(@this_conference.slug, :meals) do
= hidden_field_tag :meal, time
= button_tag :delete, value: :delete, class: [:small, :delete]
= form_tag administration_update_path(@this_conference.slug, :meals) do
.flex-inputs
= location_select nil, small: true, stretch: true
= day_select nil, small: true, format: :weekday
= time_select nil, small: true
= textfield :title, nil, required: true, big: true
= textfield :info, nil
.actions.next-prev
= button_tag :add_meal, value: :add_meal

0
app/views/conferences/admin/_schedule.html.haml

0
app/views/conferences/admin/_stats.html.haml

23
app/views/conferences/register.html.haml

@ -1,15 +1,16 @@
= render :partial => 'page_header', :locals => {:page_key => 'Conference_Registration'}
- if (steps = current_registration_steps(@registration))
= row id: 'registration-steps', class: 'flow-steps' do
= columns do
%ul
- current_registration_steps.each do | step |
- text = _"articles.conference_registration.headings.#{step[:name].to_s}"
%li{class: [step[:enabled] ? :enabled : nil, @register_template == step[:name] ? :current : nil]}
- if step[:enabled]
.step= link_to text, register_step_path(@this_conference.slug, step[:name])
- else
.step= text
= registration_step_menu
-#- if (steps = current_registration_steps(@registration))
-# = row id: 'registration-steps', class: 'flow-steps' do
-# = columns do
-# %ul
-# - current_registration_steps.each do | step |
-# - text = _"articles.conference_registration.headings.#{step[:name].to_s}"
-# %li{class: [step[:enabled] ? :enabled : nil, @register_template == step[:name] ? :current : nil]}
-# - if step[:enabled]
-# .step= link_to text, register_step_path(@this_conference.slug, step[:name])
-# - else
-# .step= text
- if @warnings.present?
= row class: 'warnings', tag: :ul do
- @warnings.each do | warning |

1
app/views/layouts/application.html.haml

@ -52,5 +52,4 @@
%button.delete=_'modals.no_button'
= yield :footer_scripts if content_for?(:footer_scripts)
- add_inline_script :main
= inline_scripts

4
app/views/shared/_footer.html.haml

@ -12,9 +12,9 @@
%ul.locales
- @alt_lang_urls.each do |locale, url|
%li
- locale_translation = _("languages.#{locale}", locale: locale)
- locale_translation = language(locale, true)
%a{href: url, lang: locale}
=_'translate.content.change_locale', "Read in #{locale_translation}", vars: {language: locale_translation}, locale: locale if locale != I18n.locale.to_s
=_'translate.content.change_locale', "Read in #{locale_translation}", vars: {language: locale_translation}, locale: locale if locale != I18n.locale.to_s
.copy
=_'links.footer.help_text.contributors', 'Who contributed to building this website' do |title|
=link_to :humans_txt, {title: title} do

2
app/views/user_mailer/broadcast.html.haml

@ -1 +1 @@
=markdown @content
=@content.html_safe

12
app/views/workshops/new.html.haml

@ -1,9 +1,3 @@
- add_stylesheet :editor
- add_inline_script :pen
- add_inline_script :markdown
- add_inline_script :editor
-#= render 'conferences/page_header', :page_key => (@workshop.id.present? ? 'Edit_Workshop' : 'Create_Workshop')
= render 'conferences/page_header', :page_key => 'Conference_Registration'
%article
@ -19,15 +13,15 @@
%h2=_@page_title, :t
- else
%h2=_@page_title, :t
= textfield :title, @title, required: true, lang: @translation, big: true, original_value: @is_translating ? @workshop.title! : nil, original_lang: @workshop.locale
= textfield :title, @title, required: true, lang: @translation, big: true, original_value: @is_translating ? @workshop.title! : nil, original_lang: @workshop.locale
= textarea :info, @info, help: 'articles.workshops.paragraphs.info', lang: @translation, original_value: @is_translating ? richtext(@workshop.info!, 4).html_safe : nil, original_lang: @workshop.locale
- if !@is_translating && (@workshop.id.blank? || @can_edit)
= columns(medium: 6) do
= checkboxes :languages, [:en, :es, :fr], @languages, 'languages', vertical: true, heading: 'articles.workshops.headings.languages', help: 'articles.workshops.paragraphs.languages'
= radiobuttons :theme, Workshop.all_themes, @workshop.theme, 'workshop.options.theme', vertical: true, heading: 'articles.workshops.headings.theme', help: 'articles.workshops.paragraphs.theme', other: true
= columns(medium: 6) do
= checkboxes :needs, [:sound, :projector, :tools], JSON.parse(@workshop.needs || '[]'), 'workshop.options.needs', vertical: true, heading: 'articles.workshops.headings.needs', help: 'articles.workshops.paragraphs.needs'
= radiobuttons :space, [:meeting_room, :workshop, :outdoor_meeting], @workshop.space, 'workshop.options.space', vertical: true, heading: 'articles.workshops.headings.space', help: 'articles.workshops.paragraphs.space'
= checkboxes :needs, Workshop.all_needs, JSON.parse(@workshop.needs || '[]'), 'workshop.options.needs', vertical: true, heading: 'articles.workshops.headings.needs', help: 'articles.workshops.paragraphs.needs'
= radiobuttons :space, Workshop.all_spaces, @workshop.space, 'workshop.options.space', vertical: true, heading: 'articles.workshops.headings.space', help: 'articles.workshops.paragraphs.space'
%h3#needs_facilitators-label=_'articles.workshops.headings.needs_facilitators','Looking for help?'
.input-field-help#needs_facilitators-desc=_'articles.workshops.paragraphs.needs_facilitators', :s, 2

2
config/initializers/assets.rb

@ -8,4 +8,4 @@ Rails.application.config.assets.version = '1.0'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
Rails.application.config.assets.precompile += %w( user-mailer.css map.js pen.js editor.js markdown.js main.js favicon.ico )
Rails.application.config.assets.precompile += %w( user-mailer.css map.js pen.js editor.js markdown.js main.js housing.js favicon.ico )

59
config/locales/en.yml

@ -35,6 +35,7 @@ en:
default: "%Y-%m-%d"
long: "%B %d, %Y"
short: "%b %d"
weekday: "%A"
span_same_month_date_1: "%B %e"
span_same_month_date_2: "%e, %Y"
span_same_year_date_1: "%B %e"
@ -87,6 +88,9 @@ en:
x_days:
one: 1 day
other: "%{count} days"
x_hours:
one: 1 hour
other: "%{count} hours"
x_minutes:
one: 1 minute
other: "%{count} minutes"
@ -96,6 +100,7 @@ en:
x_seconds:
one: 1 second
other: "%{count} seconds"
x_and_y: "%{x} %{y}"
prompts:
day: Day
hour: Hour
@ -162,6 +167,10 @@ en:
header:
one: 1 error prohibited this %{model} from being saved
other: "%{count} errors prohibited this %{model} from being saved"
warnings:
housing:
space:
overbooked: Overbooked
helpers:
select:
prompt: Please select
@ -5205,7 +5214,7 @@ en:
explain_zero_fallback: This translation will use the plural version for the
number 0
History: History
Locale_Translation: "%%{language} Translation"
Locale_Translation: "%{language} Translation"
Save: Save
content:
needs_translations: This page contains untranslated content
@ -5275,7 +5284,24 @@ en:
confirm_remove_self: Are you sure you would like to remove yourself as a facilitator of this workshop?
confirm_cancel_request: Are you sure you would like to cancel your request to become a facilitator of this workshop?
confirm_transfer_ownership: By transferring ownership, you will lose administrative capabilities such as deletion and approving new facilitators. Are you sure you want to transfer ownership to %{user_name}?
admin:
broadcast:
confirm: You are about to send this email to %{number} people. Are you sure you want to continue?
generic:
delete:
confirm: You are about to delete ‘%{title}’. Are you sure you want to continue?
articles:
admin:
housing:
headings:
guests: Guests
locations:
headings:
add_event: Add Event
add_location: Add Location
amenities: Amenities
edit_event: Edit Event
edit_location: Edit Location
policy:
headings:
The_Agreement: The Agreement
@ -5310,6 +5336,8 @@ en:
peaceful: We are peaceful and honest.
conference_registration:
headings:
Administration: Administration
administration: Administration
Policy_Agreement: Safer Space Agreement
policy: Policy
arrival_and_departure: For what days will you need housing? (If you don't
@ -5409,6 +5437,9 @@ en:
availability: The most common arrival and departure dates for attendees are the first and last day of the conference but people often arrive earlier or later. When will your space be available?
considerations: Organizers will do their best to match up hosts and guests, what considerations should organizers keep in mind when selecting guests to stay in your home?
notes: Leave a message for organizers should take into consideration when selecting guests for your household.
admin:
edit:
info: This is the copy that is displayed on the front page of the site.
host:
considerations:
vegan: Vegan or vegetarian only
@ -5587,11 +5618,16 @@ en:
message: 'Your Message:'
address: Street Address
phone: Phone number
bed_space: Bed/Couch Spaec
bed_space: Bed/Couch Space
floor_space: Floor Space
tent_space: Tent Space
first_day: From
last_day: To
body: Body
day: Day
event_location: Location
time: Time
time_span: Length
actions:
generic:
login: Sign In
@ -5616,6 +5652,11 @@ en:
next: Next
continue: Continue
facebook_sign_in: Facebook Sign In
add_meal: Add
create: Create
delete: Delete
place_guest: Place Guest
set_host: Set Host
aria:
remove_interest: Click if you are no longer interested in this workshop
show_interest: Click if you are interested in this workshop
@ -5646,6 +5687,7 @@ en:
Safer_Spaces_Policy: Safer Space Agreement
'404':
Page_Not_Found: Page Not Found
Locale_Not_Available: Locale Not Available
Policy: 'Policy'
About: 'About'
Register: 'Register'
@ -5676,6 +5718,15 @@ en:
Stats: Stats
Broadcast: Broadcast
Edit: Edit Conference
admin:
Edit: Edit
Stats: Stats
Broadcast: Broadcast
Housing: Housing
Locations: Locations
Meals: Meals
Events: Events
Schedule: Schedule
actions:
workshops:
create: New Workshop
@ -5702,6 +5753,9 @@ en:
believe that it should exist please contact admin@bikebike.org or file an
issue on github: https://github.com/bikebike/BikeBike/issues
title: '404: This page doesn''t exist'
locale_not_available:
description: This site has yet to be translated into %{language}. We are actively looking for volunteers who can translate existing copy and new copy as we add new features. If you think you can help, please contact us!
title: '404: %{language} Translations Missing'
'500':
title: There is a problem
description: 'An error has occurred, details about the error have been sent to our development team. In addition, you may contact us or report an issue.'
@ -5723,6 +5777,7 @@ en:
meeting_room: Meeting Room
outdoor_meeting: Outdoor Space
workshop: Repair Space
event_space: Event Space
theme:
community: Community Outreach
funding: Funding

2
config/routes.rb

@ -7,6 +7,8 @@ BikeBike::Application.routes.draw do
match '/conferences/:slug/register' => 'conferences#register', :as => :register, via: [:get, :post]
get '/conferences/:slug/register/:step' => 'conferences#register', :as => :register_step
get '/conferences/:slug/register/administration/:admin_step' => 'conferences#register', :as => :administration_step
post '/conferences/:slug/register/administration/update/:admin_step' => 'conferences#admin_update', :as => :administration_update
match '/conferences/:slug/broadcast' => 'conferences#broadcast', :as => :broadcast, via: [:get, :post]
get '/conferences/:slug/stats' => 'conferences#stats', :as => :stats
get '/conferences/:slug/register/:button/:confirmation_token' => 'conferences#register', :as => :register_paypal_confirm

5
db/migrate/20160621020123_add_space_to_event_locations.rb

@ -0,0 +1,5 @@
class AddSpaceToEventLocations < ActiveRecord::Migration
def change
add_column :event_locations, :space, :string
end
end

5
db/migrate/20160621051912_add_meals_to_conferences.rb

@ -0,0 +1,5 @@
class AddMealsToConferences < ActiveRecord::Migration
def change
add_column :conferences, :meals, :json
end
end

5
db/migrate/20160622011811_add_locale_to_events.rb

@ -0,0 +1,5 @@
class AddLocaleToEvents < ActiveRecord::Migration
def change
add_column :events, :locale, :string
end
end

5
db/schema.rb

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160604221432) do
ActiveRecord::Schema.define(version: 20160622011811) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -126,6 +126,7 @@ ActiveRecord::Schema.define(version: 20160604221432) do
t.string "paypal_signature"
t.string "day_parts"
t.string "registration_status"
t.json "meals"
end
create_table "delayed_jobs", force: :cascade do |t|
@ -172,6 +173,7 @@ ActiveRecord::Schema.define(version: 20160604221432) do
t.string "amenities"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "space"
end
create_table "event_types", force: :cascade do |t|
@ -194,6 +196,7 @@ ActiveRecord::Schema.define(version: 20160604221432) do
t.datetime "updated_at"
t.integer "event_location_id"
t.string "event_type"
t.string "locale"
end
create_table "locations", force: :cascade do |t|

Loading…
Cancel
Save