Added conference list page, administration tools, and re-designed conference administration

This commit is contained in:
Godwin 2016-12-11 20:02:24 -08:00
parent 08244444b0
commit 1dc608bf58
175 changed files with 12225 additions and 11806 deletions

View File

@ -1,6 +1,23 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
BikeBike::Application.load_tasks
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
BikeBike::Application.load_tasks
task regenerate_images: :environment do
{
conference: [ :cover, :poster ],
organization: [ :logo, :avatar, :cover ]
}.each do | model_class, attributes |
Object.const_get(model_class.to_s.titlecase).all.each do | model |
attributes.each do | attribute |
uploader = model.send(attribute)
if uploader.present?
puts "Regenerating #{model_class}.#{attribute} = #{uploader.url}"
uploader.recreate_versions!
end
end
end
end
end

View File

@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1000"
height="1000"
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="New document 1">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="1268.2181"
inkscape:cy="-8.1858472"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-left="0.5"
fit-margin-bottom="0.5"
fit-margin-top="0.5"
fit-margin-right="0.5"
inkscape:window-width="1920"
inkscape:window-height="1028"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid2996"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-39.499999,287.13782)">
<g
id="g3005"
transform="matrix(1.7404181,0,0,1.7404181,-29.616725,-527.44586)">
<path
sodipodi:nodetypes="ssssscccssss"
inkscape:connector-curvature="0"
id="rect3000"
d="m 71,138.36218 512,0 c 17.174,0 31,13.826 31,31 l 0,512 c 0,17.174 -13.826,31 -31,31 l -146.5,0 -45.81978,-37.88194 -44.18022,37.88194 -275.5,0 c -17.174,0 -31,-13.826 -31,-31 l 0,-512 c 0,-17.174 13.826,-31 31,-31 z"
style="fill:#3b579d;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccccccccccccccc"
inkscape:connector-curvature="0"
id="path3002"
d="m 346.5,712.36218 0,-222.5 -75,0 0,-86.5 75,0 0,-66 c 0,-69.18633 42.89263,-112.18866 110.45353,-112.18866 40.67053,0 68.04647,3.18866 68.04647,3.18866 l 0,78 -45.82143,0 c -29.03699,0 -42.67857,10.21289 -42.67857,41 l 0,56 85.5,0 -11,86.5 -74.5,0 0,222.5 z"
style="fill:#ffffff;stroke:none" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

BIN
app/assets/images/admin.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 100 125"><path d="M32.5 30.1a4.63 4.63 0 1 1-4.62-4.6 4.62 4.62 0 0 1 4.62 4.6zm58.17 42.73V91H71.3V81h-9.9V70.64h-9.88v-6a29.28 29.28 0 1 1 14.7-16.25zm-4 1.66L61.6 49.23l.4-1.15a25.4 25.4 0 1 0-9.6 11.46l3.1-2v9.08h9.88V77h9.88v10h11.4z"/></svg>

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 40"><path d="M0 25.5h7.7v5.7l7-5.7H32V.8H0v24.7zM2 2.8h28v20.7H14l-.5.4-3.8 3v-3.7H2V2.8z"/><path d="M8.8 4.7H17v2H8.8zm0 3.7h11.8v2H8.8zm0 3.6h14.5v2H8.8zm0 3.8h11.8v2H8.8zm0 3.6h8.6v2H8.8z"/></svg>

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1" viewBox="0 0 62 72.5"><path d="M0 0v58h62V0H0zm12 56H2V46h10v10zm12 0H14V46h10v10zm12 0H26V46h10v10zm12 0H38V46h10v10zm12 0H50V46h10v10zm0-36v2H50v10h10v12H50V34h-2v10H38V34h-2v10H26V34h-2v10H14V34h-2v10H2V32h10V22H2V10h10v10h2V10h10v10h2V10h10v10h2V10h10v10h2V10h10v10z"/><path d="M14 22h10v10H14zm12 0h10v10H26zm12 0h10v10H38z"/></svg>

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M76 24.6l-8-8H24v67h52v-59zM68.5 20l4 4h-4v-4zM26 81.4v-63h40.5V26H74v55.5H26z"/><path d="M30 24h20v2H30zm0 5h40v2H30zm0 5h25v2H30zm27.5 0H70v2H57.5zM30 39h40v2H30zm0 5h15v2H30zm17.5 0H70v2H47.5zM30 49h40v2H30zm0 5h17.5v2H30zm20 0h20v2H50zm-20 5h40v2H30zm0 5h7.5v2H30zm10 0h30v2H40zm-10 5h40v2H30zm0 5h40v2H30z"/></svg>

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 640"><path d="M510 209.6c0-68.5-47.8-124.2-106.6-124.2-16 0-31.8 4.3-46.3 12.5-19-42-57-70-101-70-43 0-81 28-101 70-14-9-30-13-46-13C50 85 2 141 2 209c0 59 36.8 123.2 88.4 136L65 380.4h35.6l-7.6 15c-8.2 16.4-3 36.4 12.3 46.5 5 3 8.2 8 8.8 14 1 6-1 12-5 16l11 12c8-8 12-19 11-30s-7-21-16-27c-8-5.6-11-16.5-7-25.5l11-22.4h27l-24-34c30-5 57.6-28 75.5-62.7 13 10.5 27.6 18.2 43.5 21.3L216 338h35l-7.6 15c-8.2 16.5-3 36.5 12.3 46.6 5 3.2 8.2 8.5 8.8 14.5.6 6-1.5 12-5.7 16l-8.5 9 11.7 11 8-8.5c7.8-8 11.6-18.5 10.6-29.3-1.2-11-7-20.5-16-26.5-8.4-5.5-11.3-16.4-7-25.4l11.4-22h27.5l-25-34c16-3 30.6-11 43.5-21.5 17.3 33.7 43.8 56 72.6 62.2l-25 34.5h35.7l-7.6 15c-8.3 16.5-3 36.5 12.2 46.6 5 3 8 8.5 8 14.5s-2 12-6 16l12 12c7-7.8 11-18.5 10-29-1-11-7-21-16-27-8.6-5.3-11-16.2-7-25.2l11-22.8h28l-24-33c53-11 91-76.6 91-136zM105.5 352l8.5 12H97l8.5-12zm3-21c-51.5 0-90-64-90-121.4 0-59.5 40.4-108 90-108 14 0 27.8 4 40.3 11.6-5 15-7.5 30.7-7.5 46.8 0 41 16.4 83.2 43 112-17.3 36.5-46 59-75.7 59zM256 311l8.5 12h-17l8.5-12zm0-21c-56.3 0-98.3-68.6-98.3-130 0-63.8 44-115.7 98.3-115.7s98.3 52 98.3 115.6c0 61-42 130-98.3 130zm139 74l8.5-12 8.5 12h-17zm8.4-33c-29.7 0-58.4-22.4-75.8-59 26.7-28.8 43-71 43-112 0-16-2.4-31.8-7.4-46.8 12.5-7.5 26.3-11.4 40.2-11.4 49.7 0 90.2 48.4 90.2 108 0 57-38.6 121.3-90.2 121.3z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125"><path d="M67.5 20c0-5.5-4.5-10-10-10h-15c-5.5 0-10 4.5-10 10v2.5H5V90h90V22.5H67.5V20zm-30 0c0-2.8 2.2-5 5-5h15c2.8 0 5 2.2 5 5v2.5h-25V20zm36.3 7.5V85H26.3V27.5h47.5zm-63.8 0h13.8V85H10V27.5zM90 85H76.3V27.5H90V85z"/></svg>

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 56.25"><path d="M11 37.5l.8.4V17l-.7-.5M22 13v21l.6-.3h.4V13l-.3-.3M34.2 16l-1 .6V38l1-.7"/><path fill="none" d="M25 13l-2.5-1-10.7 4.3-7.4-4v22.2l7.5 4 10-4.2 2.5 1 8 3.3 7.4-4V12.2l-7.4 4-2.4-1"/><path d="M33 14l-1.8-.6-.7 2 2.6 1 8-4v22l-8 4.3-8-3.3-2.3-1h-.2L12 38.6l-7.6-4V12.2l7.4 4L22.5 12l2.6 1-1-2.6-1-.6L12 14 2.3 9v26.7l9.4 5 10.7-4.2L33 40.8l9.6-5v-27"/><path d="M28.2 3.4c-2.3 0-4 2-4 4.2v1.2l4 10 4-10.3c.2-.3.2-.6.2-1 0-2.2-2-4-4.2-4zm0 6.2c-1 0-1.7-.8-1.7-1.8S27.3 6 28.2 6s1.8.8 1.8 1.8-.8 1.8-1.8 1.8z"/></svg>

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" class="stroked"><circle cx="386.5" cy="16.5" r="3.6"/><path stroke-width="2" d="M392 16.5c0 2.4-3.5 7.2-4.9 9.1-.3.4-.9.4-1.2 0-1.4-2-4.9-6.7-4.9-9.1 0-3 2.5-5.5 5.5-5.5s5.5 2.4 5.5 5.5z"/><circle cx="404.1" cy="45.6" r="3.6"/><path stroke-width="2" d="M409.6 45.6c0 2.4-3.5 7.2-4.9 9.1-.3.4-.9.4-1.2 0-1.4-2-4.9-6.7-4.9-9.1 0-3 2.5-5.5 5.5-5.5 3.1.1 5.5 2.5 5.5 5.5z"/><path stroke-width="2" d="M381.2.9h27.9c4.5 0 8.1 3.7 8.1 8.1v54.6c0 4.5-3.7 8.1-8.1 8.1h-27.9c-4.5 0-8.1-3.7-8.1-8.1V9.1c0-4.5 3.6-8.2 8.1-8.2z"/><path d="M382 6.1h26.4c2.4 0 4.4 2 4.4 4.4v47.7c0 2.4-2 4.4-4.4 4.4H382c-2.4 0-4.4-2-4.4-4.4V10.5c-.1-2.4 1.9-4.4 4.4-4.4z"/><circle cx="395.2" cy="67.2" r="1.9"/><line x1="388.8" y1="3.6" x2="395.8" y2="3.6"/><line x1="398.7" y1="3.6" x2="402.2" y2="3.6"/><path stroke-width="2" d="M386.5 29.3h14.3c2 0 3.7 1.7 3.7 3.7s-1.7 3.7-3.7 3.7H386c-2.1 0-3.7 1.7-3.7 3.7v14.4c0 2.1 1.7 3.7 3.7 3.7h18.5"/><polygon stroke-width="2" points="23.7,80.7 78.4,80.7 24.7,27"/><polyline stroke-width="2" points="24.7,27 27.3,24.5 80.9,78.1 78.4,80.7"/><path stroke-width="0.9766" d="M30.5 22.5h.1c2.8 0 5.1 2.3 5.1 5.1v.2c0 2.8 2.3 5.1 5.1 5.1h.4c2.8 0 5.1 2.3 5.1 5.1v.1c0 2.8 2.3 5.1 5.1 5.1h.2c2.8 0 5.1 2.3 5.1 5.1v.3c0 2.8 2.3 5.1 5.1 5.1h.3c2.8 0 5.1 2.3 5.1 5.1v.3c0 2.8 2.3 5.1 5.1 5.1h.4c2.8 0 5.1 2.3 5.1 5.1v.3c0 2.8 2.3 5.1 5.1 5.1h.2"/><path d="M68.3 57.6v.2c0 2.8 2.3 5.1 5.1 5.1h.4M57.7 47.1v.2c0 2.8 2.3 5.1 5.1 5.1h.2M47.4 36.8c0 2.8 2.3 5.1 5.1 5.1h.1M42.1 31.6h-.2c-1.7 0-3.2-.8-4.1-2.1m-.9-3.2v.2c0 .5.1 1 .2 1.4"/><rect x="22.9" y="42.6" transform="rotate(-135 60.783 44.59)" stroke-width="2" width="75.9" height="3.9"/><line stroke-width="2" x1="32.5" y1="19.3" x2="32.5" y2="20.3"/><line stroke-width="2" x1="32.6" y1="25.3" x2="32.6" y2="29.4"/><line stroke-width="2" x1="86.2" y1="72.8" x2="83" y2="72.8"/><line stroke-width="2" x1="76.6" y1="72.8" x2="75.8" y2="72.8"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 640"><path d="M92.1 227.3c-13.6 0-24.6 11-24.6 24.6 0 13.6 11 24.6 24.6 24.6s24.6-11 24.6-24.6c0-13.5-11-24.6-24.6-24.6zm0 32.8c-4.5 0-8.2-3.7-8.2-8.2 0-4.5 3.7-8.2 8.2-8.2 4.5 0 8.2 3.7 8.2 8.2 0 4.5-3.7 8.2-8.2 8.2z"/><path d="M359.9 133.8c1.7-6.9 2.6-14 2.6-21.2 0-49.7-40.4-90.1-90.1-90.1-49.7 0-90.1 40.4-90.1 90.1 0 5.9.6 11.7 1.7 17.3-7.3 1.7-14.6 3.5-21.5 5.6-16.7-24.4-44.6-39.3-74.3-39.3-26.1 0-52.1 13.5-52.1 13.5l20.5 7.7c20.7 7.8 36.8 24.3 43.9 45-29.8 17.8-52.7 40.1-66.6 65H2V342h31.8c17.5 31.3 49.5 58.6 91.1 77.7v69.8h98.3v-43.3c25 2.8 49.1 3.1 73.7.9v42.4h98.3v-66.1c72-30.1 114.8-81.6 114.8-138.7 0-66.8-58.7-125.3-150.1-150.9zm-87.5-94.9c40.7 0 73.7 33.1 73.7 73.7 0 18.3-6.6 35.7-18.8 49.2h-46.7v-9.7c9.5-3.4 16.4-12.4 16.4-23.1 0-13.6-11-24.6-24.6-24.6-4.5 0-8.2-3.7-8.2-8.2 0-4.5 3.7-8.2 8.2-8.2 4.5 0 8.2 3.7 8.2 8.2H297c0-10.7-6.9-19.7-16.4-23.1v-9.7h-16.4v9.7c-9.5 3.4-16.4 12.4-16.4 23.1 0 13.6 11 24.6 24.6 24.6 4.5 0 8.2 3.7 8.2 8.2 0 4.5-3.7 8.2-8.2 8.2-4.5 0-8.2-3.7-8.2-8.2h-16.4c0 10.7 6.9 19.7 16.4 23.1v9.7h-46.8c-12.1-13.5-18.8-30.8-18.8-49.2 0-40.7 33.1-73.7 73.8-73.7zm111.7 371.4l-5.2 2.1v60.8h-65.5v-44.3l-9.1 1c-29.3 3.3-58.1 3.1-88.1-1.1l-9.3-1.3v45.6h-65.5V409l-4.9-2.1c-42.5-18.5-74.6-45.7-90.3-76.7l-2.3-4.5H18.4v-81.9h25.4s19-45.2 70.3-70.3l5.5-3.1-1.5-6.1c-5.3-21-18-39.2-35.4-51.4 27.8-2 55 12.3 69.1 36.5l3.3 5.7s24.1-7.2 33.5-9.4c2.2 5.6 5 11 8.3 16.1h-14.6v16.4h180.3v-16.4H348c2.6-4 4.8-8.1 6.7-12.4 83.4 23.2 139 76.9 139 135.4-.1 51.3-41 98.3-109.6 125.5z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 60"><path d="M8.5 46.7V35.3h-8v-34h47v34H19.9L8.5 46.7zm-6-13.4h8v8.6l8.6-8.6h26.4v-30h-43v30z"/><path d="M23.5 28.6v-2c-1-.1-1.8-.4-2.5-.7-.6-.3-1.2-.9-1.7-1.6-.5-.7-.7-1.6-.8-2.7l2-.4c.2 1.1.4 1.9.8 2.4.6.7 1.3 1.1 2.1 1.2v-6.5c-.8-.2-1.7-.5-2.6-1-.6-.4-1.1-.9-1.5-1.5-.4-.6-.5-1.4-.5-2.2 0-1.4.5-2.6 1.5-3.5.7-.6 1.7-1 3.1-1.1V8h1.2v1c1.2.1 2.1.5 2.8 1 .9.7 1.4 1.8 1.6 3l-2 .4c-.1-.8-.4-1.4-.8-1.8-.4-.4-.9-.7-1.6-.8v5.9l2 .6c.6.3 1.2.6 1.6 1 .4.4.7.9.9 1.4.2.6.3 1.1.3 1.8 0 1.4-.4 2.6-1.3 3.5-.9.9-2.1 1.4-3.5 1.5v2.1h-1.1zm0-17.9c-.8.1-1.4.4-1.9 1-.5.5-.7 1.1-.7 1.8s.2 1.3.6 1.7c.4.5 1 .8 2 1.1v-5.6zm1.2 14.1c.8-.1 1.4-.4 2-1 .5-.6.8-1.3.8-2.2 0-.7-.2-1.3-.5-1.8-.4-.4-1.1-.9-2.2-1.2v6.2z"/></svg>

After

Width:  |  Height:  |  Size: 762 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 640"><path d="M92.1 227.3c-13.6 0-24.6 11-24.6 24.6 0 13.6 11 24.6 24.6 24.6s24.6-11 24.6-24.6c0-13.5-11-24.6-24.6-24.6zm0 32.8c-4.5 0-8.2-3.7-8.2-8.2 0-4.5 3.7-8.2 8.2-8.2 4.5 0 8.2 3.7 8.2 8.2 0 4.5-3.7 8.2-8.2 8.2z"/><path d="M359.9 133.8c1.7-6.9 2.6-14 2.6-21.2 0-49.7-40.4-90.1-90.1-90.1-49.7 0-90.1 40.4-90.1 90.1 0 5.9.6 11.7 1.7 17.3-7.3 1.7-14.6 3.5-21.5 5.6-16.7-24.4-44.6-39.3-74.3-39.3-26.1 0-52.1 13.5-52.1 13.5l20.5 7.7c20.7 7.8 36.8 24.3 43.9 45-29.8 17.8-52.7 40.1-66.6 65H2V342h31.8c17.5 31.3 49.5 58.6 91.1 77.7v69.8h98.3v-43.3c25 2.8 49.1 3.1 73.7.9v42.4h98.3v-66.1c72-30.1 114.8-81.6 114.8-138.7 0-66.8-58.7-125.3-150.1-150.9zm-87.5-94.9c40.7 0 73.7 33.1 73.7 73.7 0 18.3-6.6 35.7-18.8 49.2h-46.7v-9.7c9.5-3.4 16.4-12.4 16.4-23.1 0-13.6-11-24.6-24.6-24.6-4.5 0-8.2-3.7-8.2-8.2 0-4.5 3.7-8.2 8.2-8.2 4.5 0 8.2 3.7 8.2 8.2H297c0-10.7-6.9-19.7-16.4-23.1v-9.7h-16.4v9.7c-9.5 3.4-16.4 12.4-16.4 23.1 0 13.6 11 24.6 24.6 24.6 4.5 0 8.2 3.7 8.2 8.2 0 4.5-3.7 8.2-8.2 8.2-4.5 0-8.2-3.7-8.2-8.2h-16.4c0 10.7 6.9 19.7 16.4 23.1v9.7h-46.8c-12.1-13.5-18.8-30.8-18.8-49.2 0-40.7 33.1-73.7 73.8-73.7zm111.7 371.4l-5.2 2.1v60.8h-65.5v-44.3l-9.1 1c-29.3 3.3-58.1 3.1-88.1-1.1l-9.3-1.3v45.6h-65.5V409l-4.9-2.1c-42.5-18.5-74.6-45.7-90.3-76.7l-2.3-4.5H18.4v-81.9h25.4s19-45.2 70.3-70.3l5.5-3.1-1.5-6.1c-5.3-21-18-39.2-35.4-51.4 27.8-2 55 12.3 69.1 36.5l3.3 5.7s24.1-7.2 33.5-9.4c2.2 5.6 5 11 8.3 16.1h-14.6v16.4h180.3v-16.4H348c2.6-4 4.8-8.1 6.7-12.4 83.4 23.2 139 76.9 139 135.4-.1 51.3-41 98.3-109.6 125.5z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 640"><path d="M233.8 277.6l-25.8-43-64 106.7h224L282.7 192l-49 85.6zm-52 42.4l26.2-44 13.6 22.8-12 21.2h-28zm52.3 0l48.8-85 48.5 85h-97z"/><path d="M416 85.3h-21.3V64h-21.4V0H352v64h-21.3v21.3H181.3V64H160V0h-21.3v64h-21.4v21.3H74.7V512h362.6V85.3H416zm-64 0h21.3v21.4H352V85.3zm-213.3 0H160v21.4h-21.3V85.3zM416 490.7H96v-384h21.3V128h64v-21.3h149.4V128h64v-21.3H416v384z"/><path d="M298.7 426.7h-85.4c-6 0-10.6 4.7-10.6 10.6s4.7 10.7 10.6 10.7h85.4c6 0 10.6-4.8 10.6-10.7s-4.7-10.6-10.6-10.6zm42.6-42.7H170.7c-6 0-10.7 4.8-10.7 10.7 0 6 4.8 10.6 10.7 10.6h170.6c6 0 10.7-4.7 10.7-10.6 0-6-4.8-10.7-10.7-10.7z"/></svg>

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 80"><path d="M2.2 46.5V64h23V46.5L14 38.3 2.2 46.5zm21 15.5h-19V47.5l9.6-6.8 9.5 6.8V62z"/><path d="M0 42.4v3.3l13.8-10 13.7 10v-3.3l-13.7-9.8m25 14V64h23V46.5L50 38.3l-11.5 8.2zm21 15.4h-19V47.5l9.4-6.8 9.6 6.8V62z"/><path d="M36.5 42.4v3.3l13.7-10 13.8 10v-3.3l-13.8-9.8M20.4 14v17.4h23.2V14L32 5.6 20.4 14zm21.2 15.4H22.4V15L32 8l9.6 7v14.4z"/><path d="M45.8 10L32 0 18.2 10v3L32 3.4 45.8 13"/></svg>

After

Width:  |  Height:  |  Size: 459 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125"><path d="M71.8 33.2c7.2 0 13-5.8 13-13s-5.8-13-13-13-13 5.8-13 13c0 1.5.3 2.9.7 4.2L36.9 41c-2.3-2.3-5.6-3.7-9.1-3.7-7.2 0-13 5.8-13 13s5.8 13 13 13c3.5 0 6.8-1.4 9.1-3.7l22.6 16.6c-.4 1.3-.7 2.7-.7 4.2 0 7.2 5.8 13 13 13s13-5.8 13-13-5.8-13-13-13c-3.5 0-6.8 1.4-9.1 3.7L40.1 54.4c.4-1.3.7-2.7.7-4.2s-.3-2.9-.7-4.2l22.6-16.6c2.3 2.4 5.5 3.8 9.1 3.8zm0-20c3.9 0 7 3.1 7 7s-3.1 7-7 7-7-3.1-7-7 3.1-7 7-7zm-44 44c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.2 7-7 7zm44 16c3.9 0 7 3.1 7 7s-3.1 7-7 7-7-3.1-7-7 3.1-7 7-7z"/></svg>

After

Width:  |  Height:  |  Size: 582 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125"><path d="M38.7 72.4l34.9-22.6-34.9-22.6v45.2zm4-37.8l23.5 15.2L42.7 65V34.6z"/><path d="M50 0C22.4 0 0 22.4 0 50s22.4 50 50 50 50-22.4 50-50S77.6 0 50 0zm0 96C24.6 96 4 75.4 4 50S24.6 4 50 4s46 20.6 46 46-20.6 46-46 46z"/></svg>

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 26.25"><path d="M0 21h24V0H0v21zM19 1h4v3h-4V1zm0 4h4v3h-4V5zm0 4h4v3h-4V9zm0 4h4v3h-4v-3zm0 4h4v3h-4v-3zM14 1h4v3h-4V1zm0 4h4v3h-4V5zm0 4h4v3h-4V9zm0 4h4v3h-4v-3zm0 4h4v3h-4v-3zM9 1h4v3H9V1zm0 4h4v3H9V5zm0 4h4v3H9V9zm0 4h4v3H9v-3zm0 4h4v3H9v-3zM1 1h7v3H1V1zm0 4h7v3H1V5zm0 4h7v3H1V9zm0 4h7v3H1v-3zm0 4h7v3H1v-3z"/></svg>

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 73 67.5" class="stroked"><path stroke-width="2.5" d="M32.2 8v5.8H41v-6z"/><path d="M37.2 13.7v10m0 6.3v10m0 5.6v6.2h34v-50h-34v6m-1 6v9.8m0 6v10m0 6.4v5.8h-34v-50h34v6" stroke-width="3.5"/><path stroke-width="2.5" d="M32.2 24v5.8H41v-6zm0 16v5.8H41v-6zM8.5 13.8h18m-18 6.7h18m-18 6.3h18m-18 6.4h18m-18 6.6h18m20-26h18m-18 6.7h18m-18 6.3h18m-18 6.4h18m-18 6.6h18"/></svg>

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 112.5"><path d="M74.8 80V41.8H61.6V80H58V26.8H45V80h-3.2V42H28.6v38h-3V57.6H12.3V80h-3V10h-4v74.2H86V80H74.8zm-9-34h4.7v33.5H66V46zM49.4 31H54v48.7h-4.7V31zM33 46.3h4.5v33.5H33V46.3zM16.5 80V61.8H21V80h-4.5z"/></svg>

After

Width:  |  Height:  |  Size: 272 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125"><switch><foreignObject requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/" x="0" y="0" width="1" height="1"/><g><g fill="none" stroke="#000" stroke-width="3" stroke-miterlimit="10"><line x1="19.3" y1="50" x2="19.3" y2="57.1"/><line x1="36.8" y1="50" x2="36.8" y2="57.1"/><line x1="19.3" y1="56" x2="19.3" y2="63.1"/><line x1="36.8" y1="56" x2="36.8" y2="63.1"/><line x1="19.3" y1="62" x2="19.3" y2="69.1"/><line x1="36.8" y1="62" x2="36.8" y2="69.1"/><ellipse cx="28" cy="50" rx="8.8" ry="4.9"/><path d="M36.8 56c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5m17.6 6c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5m17.6 6c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5m17.6 6c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="19.3" y1="68" x2="19.3" y2="75.1"/><line x1="36.8" y1="68" x2="36.8" y2="75.1"/><line x1="41.3" y1="38" x2="41.3" y2="45.1"/><line x1="58.8" y1="38" x2="58.8" y2="45.1"/><line x1="41.3" y1="44" x2="41.3" y2="51.1"/><line x1="58.8" y1="44" x2="58.8" y2="51.1"/><line x1="41.3" y1="50" x2="41.3" y2="57.1"/><line x1="58.8" y1="50" x2="58.8" y2="57.1"/><line x1="41.3" y1="56" x2="41.3" y2="63.1"/><line x1="58.8" y1="56" x2="58.8" y2="63.1"/><line x1="41.3" y1="62" x2="41.3" y2="69.1"/><line x1="58.8" y1="62" x2="58.8" y2="69.1"/><ellipse cx="50" cy="38" rx="8.8" ry="4.9"/><path d="M58.8 44c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5m17.6 6c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5m17.6 6c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5m17.6 6c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5m17.6 6c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5m17.6 6c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="41.3" y1="68" x2="41.3" y2="75.1"/><line x1="58.8" y1="68" x2="58.8" y2="75.1"/><line x1="63.3" y1="26" x2="63.3" y2="33.1"/><line x1="63.3" y1="32" x2="63.3" y2="39.1"/><line x1="63.3" y1="38" x2="63.3" y2="45.1"/><line x1="63.3" y1="44" x2="63.3" y2="51.1"/><line x1="63.3" y1="50" x2="63.3" y2="57.1"/><line x1="63.3" y1="56" x2="63.3" y2="63.1"/><line x1="63.3" y1="61.1" x2="63.3" y2="68.2"/><line x1="63.3" y1="67" x2="63.3" y2="74.1"/><ellipse cx="72" cy="26" rx="8.8" ry="4.9"/><path d="M80.8 32c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="80.8" y1="26" x2="80.8" y2="33.1"/><path d="M80.8 38c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="80.8" y1="32" x2="80.8" y2="39.1"/><path d="M80.8 44c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="80.8" y1="38" x2="80.8" y2="45.1"/><path d="M80.8 50c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="80.8" y1="44" x2="80.8" y2="51.1"/><path d="M80.8 56c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="80.8" y1="50" x2="80.8" y2="57.1"/><path d="M80.8 62c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="80.8" y1="56" x2="80.8" y2="63.1"/><path d="M80.8 68c0 2.8-4 5-8.8 5s-8.8-2.2-8.8-5"/><line x1="80.8" y1="61.1" x2="80.8" y2="68.2"/><path d="M80.8 74c0 2.7-4 5-8.8 5s-8.8-2.3-8.8-5"/><line x1="80.8" y1="67" x2="80.8" y2="74.1"/></g></g></switch></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 91 113.75"><path d="M45.2 18.6C30 18.6 17.6 31 17.6 46.2 17.6 61.5 30 74 45.2 74c15.2 0 27.6-12.6 27.6-28 0-15.2-12.4-27.6-27.6-27.6zm0 52C31.8 70.6 21 59.6 21 46c0-13 10.8-24 24.2-24 13.4 0 24.2 11 24.2 24.2 0 13.4-10.8 24.3-24.2 24.3z"/><path d="M47 26.3h-3.4V48h11v-3.5H47m-3.4 17.2H47V66h-3.4zM25.2 44.5h4.4V48h-4.4zm35.6 0h4.4V48h-4.4zm-29.2-13l3.2 3-2.3 2.4-3.2-3zM58.8 61l-3.2-3 2.3-2.6 3 3zM33 62l-2.5-2 3-3.3L36 59zm24.4-31.7l2.5 2.3-3 3.2-2.8-2.3z"/></svg>

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 KiB

View File

Before

Width:  |  Height:  |  Size: 308 B

After

Width:  |  Height:  |  Size: 308 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-723 0 1000 1000" class="icons"><path d="M222.5,0.5h-891.1c-29.9,0-54,24.1-54,54v891.1c0,29.9,24.1,54,54,54h479.5V612.3h-130.5V461.7h130.5V346.8 c0-120.4,74.7-195.3,192.2-195.3c70.8,0,118.4,5.5,118.4,5.5v135.8H41.9c-50.5,0-74.3,17.8-74.3,71.4v97.5h148.8L97.2,612.3H-32.4 v387.2h255c29.9,0,54-24.1,54-54V54.5C276.5,24.6,252.4,0.5,222.5,0.5z"/></svg>

After

Width:  |  Height:  |  Size: 397 B

View File

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 470 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" class="icons"><path xmlns="http://www.w3.org/2000/svg" d="M512 0C229.25 0 0 229.2 0 512c0 226.2 146.7 418.1 350.2 485.8 25.6 4.7 34.938-11.125 34.938-24.625 0-12.188-0.469-52.562-0.719-95.312C242 908.8 211.9 817.5 211.9 817.5c-23.312-59.125-56.844-74.875-56.844-74.875-46.531-31.75 3.53-31.125 3.53-31.125 51.4 3.6 78.5 52.8 78.5 52.8 45.7 78.2 119.9 55.6 149 42.5 4.654-33 17.904-55.625 32.5-68.375C304.906 725.4 185.3 681.5 185.3 485.312c0-55.938 19.969-101.562 52.656-137.406-5.219-13-22.844-65.094 5.062-135.562 0 0 42.938-13.75 140.8 52.5 40.812-11.406 84.594-17.031 128.125-17.219 43.5 0.2 87.3 5.9 128.2 17.3 97.688-66.312 140.688-52.5 140.688-52.5 28 70.5 10.4 122.6 5.1 135.5 32.8 35.8 52.6 81.5 52.6 137.4 0 196.688-119.75 240-233.812 252.7 18.4 15.9 34.8 47 34.8 94.8 0 68.438-0.688 123.625-0.688 140.5 0 13.6 9.3 29.6 35.2 24.562C877.438 930 1024 738.1 1024 512 1024 229.2 794.8 0 512 0z"/></svg>

After

Width:  |  Height:  |  Size: 972 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,2 +1,2 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 291 288.5" id="bb-icon-logo"><path d="m290.7 136.1c-8.8.9-16.9-5.1-18.4-14-1.5-8.8 4-17.3 12.6-19.4-1.6-5.4-3.5-10.7-5.7-15.8-8 3.9-17.6 1-22.1-6.8-4.5-7.8-2.1-17.6 5.2-22.5-3.3-4.5-7-8.8-10.8-12.9-6.2 6.3-16.2 6.9-23.1 1.2-6.9-5.8-8-15.8-2.8-23-4.7-3.1-9.5-5.9-14.5-8.4-3.6 8.1-12.9 12.1-21.3 9-8.4-3.1-12.9-12.1-10.5-20.6-5.4-1.3-10.9-2.2-16.5-2.9-.6 8.8-8 15.8-16.9 15.8-9 0-16.3-7-16.9-15.8-5.5.6-10.9 1.6-16.2 2.8 2.4 8.5-2.1 17.5-10.6 20.6-8.4 3-17.7-1-21.3-9.1-5 2.5-9.9 5.3-14.5 8.4 5.2 7.2 4 17.2-2.9 23-6.9 5.7-17 5.1-23.1-1.2-3.8 4.1-7.5 8.3-10.8 12.8 7.3 5 9.6 14.8 5.1 22.6-4.5 7.8-14.2 10.6-22.1 6.7-2.2 5.1-4.1 10.4-5.8 15.8 8.6 2.2 14.1 10.6 12.6 19.4-1.6 8.8-9.7 14.8-18.5 13.9-.2 2.8-.3 5.7-.3 8.6 0 2.8.1 5.5.2 8.2 8.8-.9 16.9 5.1 18.4 14 1.5 8.8-4 17.3-12.6 19.4 1.6 5.4 3.5 10.7 5.7 15.8 8-3.9 17.6-1 22.1 6.8 4.5 7.8 2.1 17.6-5.2 22.5 3.3 4.5 7 8.8 10.8 12.9 6.2-6.3 16.2-6.9 23.1-1.2 6.9 5.8 8 15.8 2.8 23 4.7 3.1 9.5 5.9 14.5 8.4 3.6-8.1 12.9-12.1 21.3-9 8.4 3.1 12.9 12.1 10.5 20.6 5.4 1.3 10.9 2.2 16.5 2.9.6-8.8 8-15.8 16.9-15.8 9 0 16.3 7 16.9 15.8 5.5-.6 10.9-1.6 16.1-2.8-2.4-8.5 2.1-17.5 10.6-20.6 8.4-3 17.7 1 21.3 9.1 5-2.5 9.9-5.3 14.6-8.4-5.2-7.2-4-17.2 2.9-23 6.9-5.7 17-5.1 23.1 1.2 3.8-4.1 7.5-8.3 10.8-12.8-7.3-5-9.6-14.8-5.1-22.6 4.5-7.8 14.2-10.6 22.2-6.7 2.2-5.1 4.1-10.4 5.8-15.8-8.6-2.2-14.1-10.6-12.6-19.4 1.6-8.8 9.7-14.8 18.5-13.9.2-2.8.3-5.7.3-8.6-.1-2.8-.1-5.5-.3-8.2m-117.5 55.4c-.6 1.2-1.2 2.4-1.8 3.5-.6 1.1-1.2 2.1-1.9 3.1-4.5 5.8-10.2 10-17 12.6-2.6 1-5.4 1.7-8.2 2.1-2.8.4-5.8.7-8.9.9-1.6.1-3.2.1-4.8-.1-1.6-.2-3.2-.4-4.7-.5-.7 0-1.3-.1-1.9-.3-.6-.2-1.2-.3-1.9-.3-.6 0-1.1-.2-1.7-.4-.6-.3-1.2-.4-1.9-.3-.6 0-1.1-.1-1.7-.3-.6-.2-1.2-.4-1.8-.6l-57-15.5c-2.2-.6-4-1.2-5.5-1.8-1.4-.6-2.3-1.8-2.5-3.5-.1-1.1.2-2.8.8-4.9.6-2.1 1.2-3.9 1.5-5.4l30.8-114.8c.4-1.6.8-3.2 1.2-5 .4-1.8 1.1-3.1 2-4 .8-.8 1.9-1.2 3.5-1.2.3-.1.6 0 .8.1.2.1.5.2.8.1l58.3 15.6c.9.2 1.8.5 2.8.6.9.2 1.8.4 2.5.8.6.4 1.2.7 1.9.7.7 0 1.3.2 2 .5l1.2.3c.7.5 1.5.8 2.4.9.9.2 1.7.5 2.6 1 1 .5 1.9 1 2.9 1.4.9.4 1.9.9 2.9 1.4 2.2 1.6 4.3 3.1 6.3 4.5 2 1.4 3.7 3.1 5.2 4.8 2.1 2.5 3.7 5.4 4.6 8.6 1 3.2 1.5 6.7 1.6 10.5 0 1-.1 1.9-.2 2.9-.2.9-.3 2-.3 3.1 0 .6-.1 1.1-.3 1.6-.2.5-.3 1-.3 1.6 0 .4-.1.9-.3 1.5-.2.6-.4 1-.6 1.2l-.5 1.8c-.1.4-.3.8-.5 1.3-.2.5-.3.9-.4 1.1-.5.8-.9 1.6-1.1 2.3-.3.7-.6 1.3-1 1.9-3 4.2-6.2 7.5-9.7 9.8-1.2.7-2.3 1.2-3.6 1.6-1.2.4-2.4 1-3.4 1.8-.3.2-.7.5-1.2.8-.5.4-.6.9-.5 1.6 0 1.1.6 2.2 1.8 3.3 1.2 1.1 2.3 2.1 3.2 3 2.9 3.3 5 6.8 6.4 10.5 1.3 3.6 2 7.5 2.1 11.9.1 1.2.1 2.3-.1 3.4-.2 1.1-.3 2.3-.3 3.4l-.6 2.2c-.1 1.5-.6 3.4-1.4 5.7-1.2 2.6-1.9 4.3-2.6 5.6m38.9 17.5c-.2 1.2-.5 2.5-.9 4l-3.8 14.1c-.4 1.4-.8 2.7-1.2 3.9-.4 1.1-1.1 1.9-1.9 2.4-1.1.4-2.3.5-3.6.2-1.3-.3-2.7-.6-4.1-1l-13.1-3.5c-1.4-.4-2.8-.8-4.1-1.2-1.3-.4-2.2-1.1-2.6-2.1-.4-1-.6-2.1-.4-3.3.2-1.3.5-2.6.9-4.1l3.3-12.3c.3-1.3.7-2.6 1-3.8.3-1.2.9-2.2 1.6-2.8.7-.6 1.9-1 3.5-1.2.3-.1.6 0 .9.1.3.2.6.2.9.1l15.4 4.1c1.6.4 3 .8 4.4 1.3 1.4.4 2.4 1.1 3.1 2 .7.9.9 1.9.7 3.1m28.4-108.9c-.3 1.2-.6 2.4-1 3.7l-5.8 21.7c-.2.8-.4 1.7-.5 2.7-.1 1-.4 1.8-.9 2.4l-.6 2.2c-.5.8-.9 1.8-1.1 2.8-.2 1-.5 1.8-1 2.6-.4.6-.7 1.2-.8 1.8-.1.6-.4 1.2-.8 1.8-.6 1.1-1 2.2-1.3 3.3-.3 1.1-.7 2.2-1.3 3.1-.3.5-.5 1-.6 1.4-.1.5-.3.9-.6 1.4-.7 1.6-1.4 3.3-2 5.1-.6 1.8-1.4 3.5-2.2 5.1-.5.8-.8 1.7-1 2.5-.1.8-.5 1.7-1 2.7-1.2 2.2-2.1 4.6-2.8 7.1-.7 2.5-1.8 4.9-3 7-.9 1.7-1.6 3.5-2.2 5.4-.6 1.9-1.6 3.1-3.2 3.7-.5.2-1 .2-1.5.2-.6 0-1.2 0-1.9-.1l-2.7-.7c-1.3-.3-2.4-.8-3.3-1.3-.9-.5-1.5-1.2-1.9-2-.4-1-.5-1.9-.3-2.8.2-.9.4-1.9.4-3 0-1.5.2-3.1.5-4.7.4-1.6.5-3.1.5-4.7.3-1 .4-1.8.4-2.2.1-.8.2-1.6.4-2.4.2-.8.4-1.6.4-2.4 0-2 .2-4 .7-6 .5-2 .8-4 .9-6 0-.7.1-1.3.3-1.9.2-.6.3-1.2.3-1.9.1-1.2.2-2.5.5-3.8.3-1.3.5-2.7.6-4 .1-.3.1-.5.1-.8 0-.3 0-.5.1-.8 0-1.1.2-2.2.4-3.1.3-1 .4-2 .4-3.1.1-3 .7-6.2 1.6-9.6 1-3.4 1.9-6.8 2.8-10.1l4-15.1c.4-1.4.8-2.8 1.1-4.1.3-1.3 1-2.3 1.9-3.1.9-.6 1.9-.9 3.2-.8.3-.1.6 0 .8.1.2.1.5.2.8.1l15.1 4c1.6.4 3 .9 4.3 1.4 1.3.5 2.2 1.3 2.6 2.4.5.6.5 1.6.2 2.8"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 291 288.5" id="bb-icon-logo" class="icons bb-icon-logo"><path d="m290.7 136.1c-8.8.9-16.9-5.1-18.4-14-1.5-8.8 4-17.3 12.6-19.4-1.6-5.4-3.5-10.7-5.7-15.8-8 3.9-17.6 1-22.1-6.8-4.5-7.8-2.1-17.6 5.2-22.5-3.3-4.5-7-8.8-10.8-12.9-6.2 6.3-16.2 6.9-23.1 1.2-6.9-5.8-8-15.8-2.8-23-4.7-3.1-9.5-5.9-14.5-8.4-3.6 8.1-12.9 12.1-21.3 9-8.4-3.1-12.9-12.1-10.5-20.6-5.4-1.3-10.9-2.2-16.5-2.9-.6 8.8-8 15.8-16.9 15.8-9 0-16.3-7-16.9-15.8-5.5.6-10.9 1.6-16.2 2.8 2.4 8.5-2.1 17.5-10.6 20.6-8.4 3-17.7-1-21.3-9.1-5 2.5-9.9 5.3-14.5 8.4 5.2 7.2 4 17.2-2.9 23-6.9 5.7-17 5.1-23.1-1.2-3.8 4.1-7.5 8.3-10.8 12.8 7.3 5 9.6 14.8 5.1 22.6-4.5 7.8-14.2 10.6-22.1 6.7-2.2 5.1-4.1 10.4-5.8 15.8 8.6 2.2 14.1 10.6 12.6 19.4-1.6 8.8-9.7 14.8-18.5 13.9-.2 2.8-.3 5.7-.3 8.6 0 2.8.1 5.5.2 8.2 8.8-.9 16.9 5.1 18.4 14 1.5 8.8-4 17.3-12.6 19.4 1.6 5.4 3.5 10.7 5.7 15.8 8-3.9 17.6-1 22.1 6.8 4.5 7.8 2.1 17.6-5.2 22.5 3.3 4.5 7 8.8 10.8 12.9 6.2-6.3 16.2-6.9 23.1-1.2 6.9 5.8 8 15.8 2.8 23 4.7 3.1 9.5 5.9 14.5 8.4 3.6-8.1 12.9-12.1 21.3-9 8.4 3.1 12.9 12.1 10.5 20.6 5.4 1.3 10.9 2.2 16.5 2.9.6-8.8 8-15.8 16.9-15.8 9 0 16.3 7 16.9 15.8 5.5-.6 10.9-1.6 16.1-2.8-2.4-8.5 2.1-17.5 10.6-20.6 8.4-3 17.7 1 21.3 9.1 5-2.5 9.9-5.3 14.6-8.4-5.2-7.2-4-17.2 2.9-23 6.9-5.7 17-5.1 23.1 1.2 3.8-4.1 7.5-8.3 10.8-12.8-7.3-5-9.6-14.8-5.1-22.6 4.5-7.8 14.2-10.6 22.2-6.7 2.2-5.1 4.1-10.4 5.8-15.8-8.6-2.2-14.1-10.6-12.6-19.4 1.6-8.8 9.7-14.8 18.5-13.9.2-2.8.3-5.7.3-8.6-.1-2.8-.1-5.5-.3-8.2m-117.5 55.4c-.6 1.2-1.2 2.4-1.8 3.5-.6 1.1-1.2 2.1-1.9 3.1-4.5 5.8-10.2 10-17 12.6-2.6 1-5.4 1.7-8.2 2.1-2.8.4-5.8.7-8.9.9-1.6.1-3.2.1-4.8-.1-1.6-.2-3.2-.4-4.7-.5-.7 0-1.3-.1-1.9-.3-.6-.2-1.2-.3-1.9-.3-.6 0-1.1-.2-1.7-.4-.6-.3-1.2-.4-1.9-.3-.6 0-1.1-.1-1.7-.3-.6-.2-1.2-.4-1.8-.6l-57-15.5c-2.2-.6-4-1.2-5.5-1.8-1.4-.6-2.3-1.8-2.5-3.5-.1-1.1.2-2.8.8-4.9.6-2.1 1.2-3.9 1.5-5.4l30.8-114.8c.4-1.6.8-3.2 1.2-5 .4-1.8 1.1-3.1 2-4 .8-.8 1.9-1.2 3.5-1.2.3-.1.6 0 .8.1.2.1.5.2.8.1l58.3 15.6c.9.2 1.8.5 2.8.6.9.2 1.8.4 2.5.8.6.4 1.2.7 1.9.7.7 0 1.3.2 2 .5l1.2.3c.7.5 1.5.8 2.4.9.9.2 1.7.5 2.6 1 1 .5 1.9 1 2.9 1.4.9.4 1.9.9 2.9 1.4 2.2 1.6 4.3 3.1 6.3 4.5 2 1.4 3.7 3.1 5.2 4.8 2.1 2.5 3.7 5.4 4.6 8.6 1 3.2 1.5 6.7 1.6 10.5 0 1-.1 1.9-.2 2.9-.2.9-.3 2-.3 3.1 0 .6-.1 1.1-.3 1.6-.2.5-.3 1-.3 1.6 0 .4-.1.9-.3 1.5-.2.6-.4 1-.6 1.2l-.5 1.8c-.1.4-.3.8-.5 1.3-.2.5-.3.9-.4 1.1-.5.8-.9 1.6-1.1 2.3-.3.7-.6 1.3-1 1.9-3 4.2-6.2 7.5-9.7 9.8-1.2.7-2.3 1.2-3.6 1.6-1.2.4-2.4 1-3.4 1.8-.3.2-.7.5-1.2.8-.5.4-.6.9-.5 1.6 0 1.1.6 2.2 1.8 3.3 1.2 1.1 2.3 2.1 3.2 3 2.9 3.3 5 6.8 6.4 10.5 1.3 3.6 2 7.5 2.1 11.9.1 1.2.1 2.3-.1 3.4-.2 1.1-.3 2.3-.3 3.4l-.6 2.2c-.1 1.5-.6 3.4-1.4 5.7-1.2 2.6-1.9 4.3-2.6 5.6m38.9 17.5c-.2 1.2-.5 2.5-.9 4l-3.8 14.1c-.4 1.4-.8 2.7-1.2 3.9-.4 1.1-1.1 1.9-1.9 2.4-1.1.4-2.3.5-3.6.2-1.3-.3-2.7-.6-4.1-1l-13.1-3.5c-1.4-.4-2.8-.8-4.1-1.2-1.3-.4-2.2-1.1-2.6-2.1-.4-1-.6-2.1-.4-3.3.2-1.3.5-2.6.9-4.1l3.3-12.3c.3-1.3.7-2.6 1-3.8.3-1.2.9-2.2 1.6-2.8.7-.6 1.9-1 3.5-1.2.3-.1.6 0 .9.1.3.2.6.2.9.1l15.4 4.1c1.6.4 3 .8 4.4 1.3 1.4.4 2.4 1.1 3.1 2 .7.9.9 1.9.7 3.1m28.4-108.9c-.3 1.2-.6 2.4-1 3.7l-5.8 21.7c-.2.8-.4 1.7-.5 2.7-.1 1-.4 1.8-.9 2.4l-.6 2.2c-.5.8-.9 1.8-1.1 2.8-.2 1-.5 1.8-1 2.6-.4.6-.7 1.2-.8 1.8-.1.6-.4 1.2-.8 1.8-.6 1.1-1 2.2-1.3 3.3-.3 1.1-.7 2.2-1.3 3.1-.3.5-.5 1-.6 1.4-.1.5-.3.9-.6 1.4-.7 1.6-1.4 3.3-2 5.1-.6 1.8-1.4 3.5-2.2 5.1-.5.8-.8 1.7-1 2.5-.1.8-.5 1.7-1 2.7-1.2 2.2-2.1 4.6-2.8 7.1-.7 2.5-1.8 4.9-3 7-.9 1.7-1.6 3.5-2.2 5.4-.6 1.9-1.6 3.1-3.2 3.7-.5.2-1 .2-1.5.2-.6 0-1.2 0-1.9-.1l-2.7-.7c-1.3-.3-2.4-.8-3.3-1.3-.9-.5-1.5-1.2-1.9-2-.4-1-.5-1.9-.3-2.8.2-.9.4-1.9.4-3 0-1.5.2-3.1.5-4.7.4-1.6.5-3.1.5-4.7.3-1 .4-1.8.4-2.2.1-.8.2-1.6.4-2.4.2-.8.4-1.6.4-2.4 0-2 .2-4 .7-6 .5-2 .8-4 .9-6 0-.7.1-1.3.3-1.9.2-.6.3-1.2.3-1.9.1-1.2.2-2.5.5-3.8.3-1.3.5-2.7.6-4 .1-.3.1-.5.1-.8 0-.3 0-.5.1-.8 0-1.1.2-2.2.4-3.1.3-1 .4-2 .4-3.1.1-3 .7-6.2 1.6-9.6 1-3.4 1.9-6.8 2.8-10.1l4-15.1c.4-1.4.8-2.8 1.1-4.1.3-1.3 1-2.3 1.9-3.1.9-.6 1.9-.9 3.2-.8.3-.1.6 0 .8.1.2.1.5.2.8.1l15.1 4c1.6.4 3 .9 4.3 1.4 1.3.5 2.2 1.3 2.6 2.4.5.6.5 1.6.2 2.8"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -1,3 +0,0 @@
<svg height="1024" width="1024" xmlns="http://www.w3.org/2000/svg">
<path d="M512 0C229.25 0 0 229.25 0 512c0 226.25 146.688 418.125 350.156 485.812 25.594 4.688 34.938-11.125 34.938-24.625 0-12.188-0.469-52.562-0.719-95.312C242 908.812 211.906 817.5 211.906 817.5c-23.312-59.125-56.844-74.875-56.844-74.875-46.531-31.75 3.53-31.125 3.53-31.125 51.406 3.562 78.47 52.75 78.47 52.75 45.688 78.25 119.875 55.625 149 42.5 4.654-33 17.904-55.625 32.5-68.375C304.906 725.438 185.344 681.5 185.344 485.312c0-55.938 19.969-101.562 52.656-137.406-5.219-13-22.844-65.094 5.062-135.562 0 0 42.938-13.75 140.812 52.5 40.812-11.406 84.594-17.031 128.125-17.219 43.5 0.188 87.312 5.875 128.188 17.281 97.688-66.312 140.688-52.5 140.688-52.5 28 70.531 10.375 122.562 5.125 135.5 32.812 35.844 52.625 81.469 52.625 137.406 0 196.688-119.75 240-233.812 252.688 18.438 15.875 34.75 47 34.75 94.75 0 68.438-0.688 123.625-0.688 140.5 0 13.625 9.312 29.562 35.25 24.562C877.438 930 1024 738.125 1024 512 1024 229.25 794.75 0 512 0z" />
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,115 +1,130 @@
(function() {
var pens = {};
var pens = {};
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(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();
}
});
}
});
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(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) {
var name = editor.dataset.name;
pens[name] = new Pen({
editor: editor,
class: 'pen',
textarea: '<textarea name="' + name + '"></textarea>',
list: ['p', 'h1', 'h2', 'blockquote', 'insertorderedlist', 'insertunorderedlist', 'bold', 'italic', 'underline', 'strikethrough', 'createlink', 'insertimage'],
title: {
'p': 'Paragraph',
'h1': 'Major Heading',
'h2': 'Minor Heading',
'blockquote': 'Quotation',
'insertorderedlist': 'Ordered List',
'insertunorderedlist': 'Unordered List',
'bold': 'Bold',
'italic': 'Italic',
'underline': 'Underline',
'strikethrough': 'Strikethrough',
'createlink': 'Link',
'insertimage': 'Image'
}
});
return pens[name];
}
function startEditing(editor) {
var name = editor.dataset.name;
pens[name] = new Pen({
editor: editor,
class: 'pen',
textarea: '<textarea name="' + name + '"></textarea>',
list: ['p', 'h1', 'h2', 'blockquote', 'insertorderedlist', 'insertunorderedlist', 'bold', 'italic', 'underline', 'strikethrough', 'createlink', 'insertimage'],
title: {
'p': 'Paragraph',
'h1': 'Major Heading',
'h2': 'Minor Heading',
'blockquote': 'Quotation',
'insertorderedlist': 'Ordered List',
'insertunorderedlist': 'Unordered List',
'bold': 'Bold',
'italic': 'Italic',
'underline': 'Underline',
'strikethrough': 'Strikethrough',
'createlink': 'Link',
'insertimage': 'Image'
}
});
return pens[name];
}
Array.prototype.forEach.call(document.querySelectorAll('form'), function(form) {
var shouldAllowAlert = false;
form.addEventListener('submit', function() {
if (shouldAllowAlert) {
return;
}
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(editor) {
var name = editor.dataset.name;
var textarea = document.querySelector('textarea[name="' + name + '"]');
if (!textarea) {
textarea = document.createElement('textarea');
textarea.name = name;
textarea.style.display = 'none';
form.appendChild(textarea);
}
textarea.value = editor.innerHTML;
if (pens[name]) {
pens[name].destroy();
}
});
}, false);
Array.prototype.forEach.call(form.querySelectorAll('button'), function(button) {
form.addEventListener('click', function(event) {
shouldAllowAlert = (event.target.value === 'cancel');
});
});
});
Array.prototype.forEach.call(document.querySelectorAll('form'), function(form) {
var shouldAllowAlert = false;
form.addEventListener('submit', function() {
if (shouldAllowAlert) {
return;
}
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(editor) {
var name = editor.dataset.name;
var textarea = document.querySelector('textarea[name="' + name + '"]');
if (!textarea) {
textarea = document.createElement('textarea');
textarea.name = name;
textarea.style.display = 'none';
form.appendChild(textarea);
}
textarea.value = editor.innerHTML;
if (pens[name]) {
pens[name].destroy();
}
});
}, false);
Array.prototype.forEach.call(form.querySelectorAll('button'), function(button) {
form.addEventListener('click', function(event) {
shouldAllowAlert = (event.target.value === 'cancel');
});
});
});
Array.prototype.forEach.call(document.querySelectorAll('.check-box-field .other input'), function(input) {
var checkbox = document.getElementById(input.parentElement.parentElement.attributes.for.value);
input.addEventListener('keyup', function(event) {
if (event.target.value) {
checkbox.checked = true;
}
});
input.addEventListener('click', function(event) {
checkbox.checked = true;
});
var setRequired = function() {
if (checkbox.checked) {
input.setAttribute('required', 'required');
} else {
input.removeAttribute('required');
}
};
Array.prototype.forEach.call(document.querySelectorAll('.check-box-field input'), function(_input) {
_input.addEventListener('change', function(event) { setRequired(); });
});
});
Array.prototype.forEach.call(document.querySelectorAll('.check-box-field .other input'), function(input) {
var checkbox = document.getElementById(input.parentElement.parentElement.attributes.for.value);
input.addEventListener('keyup', function(event) {
if (event.target.value) {
checkbox.checked = true;
}
});
input.addEventListener('click', function(event) {
checkbox.checked = true;
});
var setRequired = function() {
if (checkbox.checked) {
input.setAttribute('required', 'required');
} else {
input.removeAttribute('required');
}
};
Array.prototype.forEach.call(document.querySelectorAll('.check-box-field input'), function(_input) {
_input.addEventListener('change', function(event) { setRequired(); });
});
});
Array.prototype.forEach.call(document.querySelectorAll('[data-toggles]'), function(checkbox) {
var toggles = document.getElementById(checkbox.dataset.toggles);
toggles.classList.add('toggleable');
var form = checkbox.parentNode;
while (form && form.nodeName != 'FORM') {
form = form.parentNode;
}
var toggle = function() {
toggles.classList[checkbox.checked ? 'add' : 'remove']('open');
if (form) {
if (checkbox.checked) {
form.removeAttribute('novalidate');
} else {
form.setAttribute('novalidate', 'novalidate');
}
}
};
toggle();
checkbox.addEventListener('change', function(event) { toggle(); });
});
Array.prototype.forEach.call(document.querySelectorAll('[data-toggles]'), function(checkbox) {
var toggles = document.getElementById(checkbox.dataset.toggles);
toggles.classList.add('toggleable');
var form = checkbox.parentNode;
while (form && form.nodeName != 'FORM') {
form = form.parentNode;
}
var toggle = function() {
toggles.classList[checkbox.checked ? 'add' : 'remove']('open');
if (form) {
if (checkbox.checked) {
form.removeAttribute('novalidate');
} else {
form.setAttribute('novalidate', 'novalidate');
}
}
};
toggle();
checkbox.addEventListener('change', function(event) { toggle(); });
});
Array.prototype.forEach.call(document.querySelectorAll('fieldset.translator'), function(translator) {
Array.prototype.forEach.call(translator.querySelectorAll('.locale-select a'), function(selector) {
selector.addEventListener('click', function(event) {
event.preventDefault();
var locale = event.target.parentElement.getAttribute('data-locale');
Array.prototype.forEach.call(translator.querySelectorAll('.locale-select li'), function(_selector) {
_selector.className = _selector.getAttribute('data-locale') == locale ? 'selected' : '';
});
Array.prototype.forEach.call(translator.querySelectorAll('.text-editors li'), function(editor) {
editor.className = editor.getAttribute('data-locale') == locale ? 'selected' : '';
});
});
});
});
})();

View File

@ -0,0 +1,31 @@
(function() {
document.addEventListener('DOMContentLoaded', function() {
var fields = document.getElementsByClassName('file-field');
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var input = field.getElementsByTagName('input')[0];
var image = field.getElementsByTagName('img')[0];
var state = field.getElementsByClassName('file-field-name')[0];
input.onchange = function() {
state.className = 'file-field-name selected';
state.innerHTML = this.value.split(/[\/\\]/).reverse()[0];
var uploadButton = this.form.querySelector('[value="upload"]');
if (uploadButton) {
uploadButton.setAttribute('data-enabled', '1');
}
if (this.files && this.files[0] && typeof FileReader !== "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
image.className = 'changed';
image.src = e.target.result;
};
reader.readAsDataURL(this.files[0]);
}
}
}
}, false);
})();

File diff suppressed because one or more lines are too long

View File

@ -230,4 +230,15 @@
});
};
initNode();
document.addEventListener('DOMContentLoaded', function() {
var errors = document.getElementsByClassName('has-error');
if (errors.length <= 0) {
errors = document.getElementsByClassName('info-message');
}
if (errors.length > 0) {
errors[0].scrollIntoView();
}
});
})();

View File

@ -0,0 +1,117 @@
(function() {
function loadMap() {
var projection = d3.geo.mercator();
var path = d3.geo.path().projection(projection);
var tooltip = document.getElementById('tooltip');
var initialScale = 3.5;
var initialPosition = [-100, -175];
var zoom = d3.behavior.zoom()
.scaleExtent([1, 20])
.scale(initialScale).translate(initialPosition)
.on("zoom", function() {
setZoom(d3.event.translate, d3.event.scale);
});
function setZoom(translate, scale) {
container.attr("transform", "translate(" + translate + ") scale(" + scale + ")").attr('data-scale', scale);
}
var container = d3.select('#map').call(zoom).insert('g', ':first-child').attr('class', 'map');
setZoom(initialPosition, initialScale);
container.append("path")
.datum(d3.geo.graticule())
.attr("class", "graticule")
.attr("d", path);
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
d3.json('/assets/world-110m.json', function(error, world) {
if (error) {
throw error;
}
container.selectAll('path')
.data(topojson.feature(world, world.objects.countries).features)
.enter()
.append('path')
.attr('d', path)
.attr('class', 'country');
var year = (new Date()).getFullYear();
var conferences = document.querySelectorAll('#conferences .conference');
var conference_path = []
for (var i = 0; i < conferences.length; i++) {
var d = conferences[i];
if (d.getAttribute('data-t') === 'annual') {
var coords = projection([d.getAttribute('data-o'), d.getAttribute('data-a')]);
if (conference_path.length) {
conference_path[conference_path.length - 1].x2 = coords[0];
conference_path[conference_path.length - 1].y2 = coords[1];
}
conference_path.push({
x1: coords[0],
y1: coords[1]
});
}
}
container.append('defs').html('<filter id="svg-gooey-filter"><feGaussianBlur in="SourceGraphic" stdDeviation="3" result="blur"></feGaussianBlur><feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="svg-gooey-filter"></feColorMatrix><feComposite in="SourceGraphic" in2="svg-gooey-filter" operator="atop"></feComposite></filter>')
var regionalConferences = container.append('g').attr('filter', 'url(#svg-gooey-filter)').attr('class', 'cities regional-conferences');
var annualConferences = container.append('g').attr('filter', 'url(#svg-gooey-filter)').attr('class', 'cities annual-conferences');
function mouseover(e) {
c = document.getElementById('conference-' + event.target.getAttribute('data-c'));
tooltip.innerHTML = '<h3>' + c.querySelector('.title').innerHTML + '</h3>' +
'<div class="conference-details">' + c.querySelector('.conference-details').innerHTML + '</div>';
tooltip.className = 'open';
}
function mouseout(e) {
tooltip.className = '';
}
function click(e) {
l = document.querySelector('#conference-' + event.target.getAttribute('data-c') + ' .conference-link');
window.location.href = l.getAttribute('href');
}
for (var i = conferences.length - 1; i >= 0; i--) {
var c = conferences[i];
var type = c.getAttribute('data-t');
var coords = projection([c.getAttribute('data-o'), c.getAttribute('data-a')]);
(type === 'annual' ? annualConferences : regionalConferences)
.append('circle')
.attr('class', 'city type-' + type)
.attr('data-c', c.id.replace(/^conference\-/, ''))
.attr('cx', function(d) { return coords[0]; })
.attr('cy', function(d) { return coords[1]; })
.attr('r', Math.max(3,
(15 - (
(year - parseInt(c.getAttribute('data-y'))) * 2.5)) * 1.125)
)
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.on('click', click);
}
});
d3.select("#map").attr('class', 'loaded');
}
document.onreadystatechange = function () {
if (document.readyState == 'complete') {
loadMap();
}
};
})();

View File

@ -0,0 +1,26 @@
(function() {
function find_user(email, f) {
var request = new XMLHttpRequest();
request.open('POST', '/user/find', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
request.setRequestHeader('X-CSRF-Token', encodeURI(document.querySelector('meta[name="csrf-token"]').getAttribute('content')));
request.send('e=' + encodeURI(email));
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
f(JSON.parse(request.responseText));
} else {
f({error: request.status});
}
}
}
}
document.addEventListener('DOMContentLoaded', function() {
var fields = document.getElementsByClassName('user-field');
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var input = field.getElementsByTagName('input')[0];
var name = field.getElementsByClassName('user-name')[0];
}
}, false);
})();

File diff suppressed because it is too large Load Diff

View File

@ -14,156 +14,165 @@ $colour-5: #02CA9E; // green
$white: #FFFEFE;
$black: #333;
$gray: #E8E8E8;
$light-gray: #EEE;
$mid-gray: #888;
// $red: #B24C63;
$red: #FF5A5F;
$link-colour: darken($colour-1, 13%);
@mixin default-box-shadow($direction: top, $distance: 1, $inset: false, $additional-shadow: false) {
@if capable_of(box-shadow) {
$offset: 0.2em;
@if $direction == right or $direction == bottom {
$offset: -$offset;
}
@if $direction == left or $direction == right {
$offset: '#{$offset} 0';
} @else {
$offset: '0 #{$offset}';
}
@if $inset {
$offset: 'inset #{$offset}';
}
@if $additional-shadow {
$additional-shadow: ', #{$additional-shadow}';
} @else {
$additional-shadow: '';
}
@include _(box-shadow, #{$offset} 0.8em #{-0.2em * $distance} #000#{$additional-shadow});
}
@if capable_of(box-shadow) {
$offset: 0.2em;
@if $direction == right or $direction == bottom {
$offset: -$offset;
}
@if $direction == left or $direction == right {
$offset: '#{$offset} 0';
} @else {
$offset: '0 #{$offset}';
}
@if $inset {
$offset: 'inset #{$offset}';
}
@if $additional-shadow {
$additional-shadow: ', #{$additional-shadow}';
} @else {
$additional-shadow: '';
}
@include _(box-shadow, #{$offset} 0.8em #{-0.2em * $distance} #000#{$additional-shadow});
}
}
@mixin monospace-font {
@include font(monospace);
@include font(monospace-bold);
@include font(monospace);
@include font(monospace-bold);
}
@mixin translation-pointer {
@include keyframes(bouncy) {
from { transform: translateY(-0.25em); }
to { transform: translateY(0.25em); }
}
@include keyframes(bouncy) {
from { transform: translateY(-0.25em); }
to { transform: translateY(0.25em); }
}
#lingua-franca-pointer {
$colour: $colour-5;
width: 0.6667em;
height: 1.25em;
background-color: $colour;
z-index: 1000;
margin-left: -0.5em;
margin-top: -2em;
@include _(mix-blend-mode, exclusion);
@include default-box-shadow(top, 2);
@include _(animation, bouncy 1s infinite alternate);
#lingua-franca-pointer {
$colour: $colour-5;
width: 0.6667em;
height: 1.25em;
background-color: $colour;
z-index: 1000;
margin-left: -0.5em;
margin-top: -2em;
@include _(mix-blend-mode, exclusion);
@include default-box-shadow(top, 2);
@include _(animation, bouncy 1s infinite alternate);
$twidth: 0.8em;
@include after {
content: '';
width: 0;
height: 0;
position: absolute;
border-style: solid;
border-color: $colour transparent transparent;
border-width: $twidth $twidth 0;
top: 100%;
left: -.4em;
}
$twidth: 0.8em;
@include after {
content: '';
width: 0;
height: 0;
position: absolute;
border-style: solid;
border-color: $colour transparent transparent;
border-width: $twidth $twidth 0;
top: 100%;
left: -.4em;
}
&.up {
margin-top: 2em;
&.up {
margin-top: 2em;
@include after {
top: auto;
bottom: 100%;
border-color: transparent transparent $colour;
border-width: 0 $twidth $twidth;
}
}
}
@include after {
top: auto;
bottom: 100%;
border-color: transparent transparent $colour;
border-width: 0 $twidth $twidth;
}
}
}
}
@mixin text-stroke {
@include _(text-stroke, 1px rgba(0, 0, 0, 0.25));
}
@mixin button {
position: relative;
display: inline-block;
color: $white;
background-color: $colour-1;
border: 0;
padding: 0.5em 1em;
font-size: 1.25em;
outline: 0;
border-bottom: 0.125em solid rgba(0, 0, 0, 0.15);
@include _(border-radius, 0.15em);
@include default-box-shadow(top, 2);
overflow: hidden;
cursor: pointer;
@include _(text-stroke, 1px rgba(0, 0, 0, 0.25));
position: relative;
display: inline-block;
color: $white;
background-color: $colour-1;
border: 0;
padding: 0.5em 1em;
font-size: 1.25em;
outline: 0;
border-bottom: 0.125em solid rgba(0, 0, 0, 0.15);
@include _(border-radius, 0.15em);
@include default-box-shadow(top, 2);
overflow: hidden;
cursor: pointer;
@include text-stroke;
@include before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0);
@include _(transition, background-color 150ms ease-in-out);
}
/*@include before-and-after {
content: '';
position: absolute;
display: block;
top: 0;
right: 100%;
font-size: 1.15em;
background-color: rgba(0, 0, 0, 0);
border-color: transparent;
@include _(transition, all 250ms ease-in-out);
}
@include before {
height: 100%;
width: 100%;
margin-right: 1em;
}
@include after {
border-style: solid;
border-width: 1em 0 1em 1em;
}*/
@include before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0);
@include _(transition, background-color 150ms ease-in-out);
}
/*@include before-and-after {
content: '';
position: absolute;
display: block;
top: 0;
right: 100%;
font-size: 1.15em;
background-color: rgba(0, 0, 0, 0);
border-color: transparent;
@include _(transition, all 250ms ease-in-out);
}
@include before {
height: 100%;
width: 100%;
margin-right: 1em;
}
@include after {
border-style: solid;
border-width: 1em 0 1em 1em;
}*/
/*&:hover,
&:focus {
@include before-and-after {
right: -1em;
border-left-color: rgba(0, 0, 0, 0.15);
}
}*/
&:hover,
&:focus {
@include before {
background-color: rgba(0, 0, 0, 0.15);
}
}
/*&:hover,
&:focus {
@include before-and-after {
right: -1em;
border-left-color: rgba(0, 0, 0, 0.15);
}
}*/
&:hover,
&:focus {
@include before {
background-color: rgba(0, 0, 0, 0.15);
}
}
&:active {
@include _(transform, scale(0.95));
&:active {
@include _(transform, scale(0.95));
@include after {
left: 120%;
}
}
@include after {
left: 120%;
}
}
&:disabled {
@include _(opacity, 0.5);
cursor: inherit;
&:disabled {
@include _(opacity, 0.5);
cursor: inherit;
@include before-and-after {
display: none;
}
}
@include before-and-after {
display: none;
}
}
}

View File

@ -5,8 +5,8 @@
"chrome": ["51"]
},
"development": {
"and_chr": ["53"],
"chrome": ["53"],
"and_chr": ["54"],
"chrome": ["54"],
"edge": ["13"],
"firefox": ["44"],
"ie": ["11"],

View File

@ -0,0 +1,36 @@
require 'geocoder/calculations'
class AdminController < ApplicationController
def new
return do_404 unless logged_in? && current_user.administrator?
@this_conference = Conference.new
@page_title = 'articles.conferences.headings.new'
end
def edit
return do_404 unless logged_in? && current_user.administrator?
@this_conference = Conference.find_by!(slug: params[:slug])
@page_title = 'articles.conferences.headings.edit'
render 'new'
end
def save
conference = params[:id].present? ? Conference.find_by!(id: params[:id]) : Conference.new
if params[:button] == 'save'
city = City.search(params[:city])
conference.city_id = city.id
conference.conferencetype = params[:type]
conference.year = params[:year].to_i
conference.is_public = params[:is_public].present?
conference.is_featured = params[:is_featured].present?
conference.make_slug(true)
conference.save!
elsif params[:button] == 'delete'
conference.destroy
return redirect_to conferences_url
end
redirect_to conference_url(conference.slug)
end
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,355 @@
class WorkshopsController < ApplicationController
def workshops
set_conference
set_conference_registration!
@workshops = Workshop.where(:conference_id => @this_conference.id)
@my_workshops = Workshop.joins(:workshop_facilitators).where(:workshop_facilitators => {:user_id => current_user.id}, :conference_id => @this_conference.id)
render 'workshops/index'
end
def view_workshop
set_conference
set_conference_registration!
@workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless @workshop
@translations_available_for_editing = []
I18n.backend.enabled_locales.each do |locale|
@translations_available_for_editing << locale if @workshop.can_translate?(current_user, locale)
end
@page_title = 'page_titles.conferences.View_Workshop'
@register_template = :workshops
render 'workshops/show'
end
def create_workshop
set_conference
set_conference_registration!
@workshop = Workshop.new
@languages = [I18n.locale.to_sym]
@needs = []
@page_title = 'page_titles.conferences.Create_Workshop'
@register_template = :workshops
render 'workshops/new'
end
def translate_workshop
@is_translating = true
@translation = params[:locale]
@page_title = 'page_titles.conferences.Translate_Workshop'
@page_title_vars = { language: view_context.language_name(@translation) }
@register_template = :workshops
edit_workshop
end
def edit_workshop
set_conference
set_conference_registration!
@workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless @workshop.present?
@page_title ||= 'page_titles.conferences.Edit_Workshop'
@can_edit = @workshop.can_edit?(current_user)
@is_translating ||= false
if @is_translating
return do_404 if @translation.to_s == @workshop.locale.to_s || !I18n.backend.enabled_locales.include?(@translation.to_s)
return do_403 unless @workshop.can_translate?(current_user, @translation)
@title = @workshop._title(@translation)
@info = @workshop._info(@translation)
else
return do_403 unless @can_edit
@title = @workshop.title
@info = @workshop.info
end
@needs = JSON.parse(@workshop.needs || '[]').map &:to_sym
@languages = JSON.parse(@workshop.languages || '[]').map &:to_sym
@space = @workshop.space.to_sym if @workshop.space
@theme = @workshop.theme.to_sym if @workshop.theme
@notes = @workshop.notes
@register_template = :workshops
render 'workshops/new'
end
def delete_workshop
set_conference
set_conference_registration!
@workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless @workshop.present?
return do_403 unless @workshop.can_delete?(current_user)
if request.post?
if params[:button] == 'confirm'
if @workshop
@workshop.workshop_facilitators.destroy_all
@workshop.destroy
end
return redirect_to register_step_path(@this_conference.slug, 'workshops')
end
return redirect_to view_workshop_url(@this_conference.slug, @workshop.id)
end
@register_template = :workshops
render 'workshops/delete'
end
def save_workshop
set_conference
set_conference_registration!
if params[:button].to_sym != :save
if params[:workshop_id].present?
return redirect_to view_workshop_url(@this_conference.slug, params[:workshop_id])
end
return redirect_to register_step_path(@this_conference.slug, 'workshops')
end
if params[:workshop_id].present?
workshop = Workshop.find(params[:workshop_id])
return do_404 unless workshop.present?
can_edit = workshop.can_edit?(current_user)
else
workshop = Workshop.new(:conference_id => @this_conference.id)
workshop.workshop_facilitators = [WorkshopFacilitator.new(:user_id => current_user.id, :role => :creator)]
can_edit = true
end
title = params[:title]
info = params[:info].gsub(/^\s*(.*?)\s*$/, '\1')
if params[:translation].present? && workshop.can_translate?(current_user, params[:translation])
old_title = workshop._title(params[:translation])
old_info = workshop._info(params[:translation])
do_save = false
unless title == old_title
workshop.set_column_for_locale(:title, params[:translation], title, current_user.id)
do_save = true
end
unless info == old_info
workshop.set_column_for_locale(:info, params[:translation], info, current_user.id)
do_save = true
end
# only save if the text has changed, if we want to make sure only to update the translator id if necessary
workshop.save_translations if do_save
elsif can_edit
workshop.title = title
workshop.info = info
workshop.languages = (params[:languages] || {}).keys.to_json
workshop.needs = (params[:needs] || {}).keys.to_json
workshop.theme = params[:theme] == 'other' ? params[:other_theme] : params[:theme]
workshop.space = params[:space]
workshop.notes = params[:notes]
workshop.needs_facilitators = params[:needs_facilitators].present?
workshop.save
# Rouge nil facilitators have been know to be created, just destroy them here now
WorkshopFacilitator.where(:user_id => nil).destroy_all
else
return do_403
end
redirect_to view_workshop_url(@this_conference.slug, workshop.id)
end
def toggle_workshop_interest
set_conference
set_conference_registration!
workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless workshop
# save the current state
interested = workshop.interested? current_user
# remove all associated fields
WorkshopInterest.delete_all(:workshop_id => workshop.id, :user_id => current_user.id)
# creat the new interest row if we weren't interested before
WorkshopInterest.create(:workshop_id => workshop.id, :user_id => current_user.id) unless interested
if request.xhr?
render json: [
{
selector: '.interest-button',
html: view_context.interest_button(workshop)
},
{
selector: '.interest-text',
html: view_context.interest_text(workshop)
}
]
else
# go back to the workshop
redirect_to view_workshop_url(@this_conference.slug, workshop.id)
end
end
def facilitate_workshop
set_conference
set_conference_registration!
@workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless @workshop
return do_403 if @workshop.facilitator?(current_user) || !current_user
@register_template = :workshops
render 'workshops/facilitate'
end
def facilitate_request
set_conference
set_conference_registration!
workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless workshop
return do_403 if workshop.facilitator?(current_user) || !current_user
# create the request by making the user a facilitator but making their role 'requested'
WorkshopFacilitator.create(user_id: current_user.id, workshop_id: workshop.id, role: :requested)
UserMailer.send_mail :workshop_facilitator_request do
{
:args => [ workshop, current_user, params[:message] ]
}
end
redirect_to sent_facilitate_workshop_url(@this_conference.slug, workshop.id)
end
def sent_facilitate_request
set_conference
set_conference_registration!
@workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless @workshop
return do_403 unless @workshop.requested_collaborator?(current_user)
@register_template = :workshops
render 'workshops/facilitate_request_sent'
end
def approve_facilitate_request
return do_403 unless logged_in?
set_conference
set_conference_registration!
workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless workshop.present?
user_id = params[:user_id].to_i
action = params[:approve_or_deny].to_sym
user = User.find(user_id)
case action
when :approve
if workshop.active_facilitator?(current_user) && workshop.requested_collaborator?(User.find(user_id))
f = WorkshopFacilitator.find_by_workshop_id_and_user_id(
workshop.id, user_id)
f.role = :collaborator
f.save
UserMailer.send_mail :workshop_facilitator_request_approved, user.locale do
[ workshop, user ]
end
return redirect_to view_workshop_url(@this_conference.slug, workshop.id)
end
when :deny
if workshop.active_facilitator?(current_user) && workshop.requested_collaborator?(User.find(user_id))
WorkshopFacilitator.delete_all(
:workshop_id => workshop.id,
:user_id => user_id)
UserMailer.send_mail :workshop_facilitator_request_denied, user.locale do
[ workshop, user ]
end
return redirect_to view_workshop_url(@this_conference.slug, workshop.id)
end
when :remove
if workshop.can_remove?(current_user, user)
WorkshopFacilitator.delete_all(
:workshop_id => workshop.id,
:user_id => user_id)
return redirect_to view_workshop_url(@this_conference.slug, workshop.id)
end
when :switch_ownership
if workshop.creator?(current_user)
f = WorkshopFacilitator.find_by_workshop_id_and_user_id(
workshop.id, current_user.id)
f.role = :collaborator
f.save
f = WorkshopFacilitator.find_by_workshop_id_and_user_id(
workshop.id, user_id)
f.role = :creator
f.save
return redirect_to view_workshop_url(@this_conference.slug, workshop.id)
end
end
return do_403
end
def add_workshop_facilitator
set_conference
set_conference_registration!
user = User.find_by_email(params[:email])
# create the user if they don't exist and send them a link to register
unless user
user = User.create(email: params[:email])
generate_confirmation(user, register_path(@this_conference.slug))
end
workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless workshop && current_user
unless workshop.facilitator?(user)
WorkshopFacilitator.create(user_id: user.id, workshop_id: workshop.id, role: :collaborator)
UserMailer.send_mail :workshop_facilitator_request_approved, user.locale do
[ workshop, user ]
end
end
return redirect_to view_workshop_url(@this_conference.slug, params[:workshop_id])
end
def add_comment
set_conference
set_conference_registration!
workshop = Workshop.find_by_id_and_conference_id(params[:workshop_id], @this_conference.id)
return do_404 unless workshop && current_user
if params[:button] == 'reply'
comment = Comment.find_by!(id: params[:comment_id].to_i, model_type: :workshops, model_id: workshop.id)
new_comment = comment.add_comment(current_user, params[:reply])
unless comment.user.id == current_user.id
UserMailer.send_mail :workshop_comment, comment.user.locale do
[ workshop, new_comment, comment.user ]
end
end
elsif params[:button] = 'add_comment'
new_comment = workshop.add_comment(current_user, params[:comment])
workshop.active_facilitators.each do | u |
unless u.id == current_user.id
UserMailer.send_mail :workshop_comment, u.locale do
[ workshop, new_comment, u ]
end
end
end
else
return do_404
end
return redirect_to view_workshop_url(@this_conference.slug, workshop.id, anchor: "comment-#{new_comment.id}")
end
end

File diff suppressed because it is too large Load Diff

View File

@ -1,180 +1,180 @@
require 'diffy'
class UserMailer < ActionMailer::Base
add_template_helper(ApplicationHelper)
include LinguaFrancaHelper
add_template_helper(ApplicationHelper)
include LinguaFrancaHelper
before_filter :set_host
before_filter :set_host
default from: "Bike!Bike! <noreply@bikebike.org>"
default from: "Bike!Bike! <noreply@bikebike.org>"
def email_confirmation(confirmation)
@confirmation = EmailConfirmation.find(confirmation) if confirmation.present?
I18n.locale = @confirmation.user.locale if @confirmation.user.locale.present?
@subject = _'email.subject.confirm_email','Please confirm your email address'
mail to: @confirmation.user.named_email, subject: @subject
end
def email_confirmation(confirmation)
@confirmation = EmailConfirmation.find(confirmation) if confirmation.present?
I18n.locale = @confirmation.user.locale if @confirmation.user.locale.present?
@subject = _'email.subject.confirm_email','Please confirm your email address'
mail to: @confirmation.user.named_email, subject: @subject
end
def registration_confirmation(registration)
@registration = ConferenceRegistration.find(registration) if registration.present?
@conference = @registration.conference
@user = @registration.user
I18n.locale = @user.locale if @user.locale.present?
@subject = @conference.registration_status.to_sym == :pre ?
_(
'email.subject.pre_registration_confirmed',
"Thank you for pre-registering for #{@conference.title}",
:vars => {:conference_title => @conference.title}
) : _(
'email.subject.registration_confirmed',
"Thank you for registering for #{@conference.title}",
:vars => {:conference_title => @conference.title}
)
mail to: @user.named_email, subject: @subject
end
def registration_confirmation(registration)
@registration = ConferenceRegistration.find(registration) if registration.present?
@conference = @registration.conference
@user = @registration.user
I18n.locale = @user.locale if @user.locale.present?
@subject = @conference.registration_status.to_sym == :pre ?
_(
'email.subject.pre_registration_confirmed',
"Thank you for pre-registering for #{@conference.title}",
:vars => {:conference_title => @conference.title}
) : _(
'email.subject.registration_confirmed',
"Thank you for registering for #{@conference.title}",
:vars => {:conference_title => @conference.title}
)
mail to: @user.named_email, subject: @subject
end
def broadcast(host, subject, content, user, conference)
@host = host
@content = content
@banner = nil
@conference = Conference.find(conference) if conference.present?
@user = User.find(user) if user.present?
@subject = "[#{@conference ? @conference.title : 'Bike!Bike!'}] #{subject}"
if @user && @user.named_email
mail to: @user.named_email, subject: @subject
end
end
def broadcast(host, subject, content, user, conference)
@host = host
@content = content
@banner = nil
@conference = Conference.find(conference) if conference.present?
@user = User.find(user) if user.present?
@subject = "[#{@conference ? @conference.title : 'Bike!Bike!'}] #{subject}"
if @user && @user.named_email
mail to: @user.named_email, subject: @subject
end
end
def workshop_facilitator_request(workshop, requester, message)
@workshop = Workshop.find(workshop) if workshop.present?
@requester = User.find(requester) if requester.present?
addresses = []
I18n.locale = @workshop.active_facilitators.first.locale if @workshop.active_facilitators.first.locale.present?
@workshop.active_facilitators.each do |f|
addresses << f.named_email
end
@message = message
@conference = Conference.find(@workshop.conference_id)
@subject = _('email.subject.workshop_facilitator_request',
"Request to facilitate #{@workshop.title} from #{@requester.name}",
:vars => {:workshop_title => @workshop.title, :requester_name => @requester.firstname})
mail to: addresses, reply_to: addresses + [@requester.named_email], subject: @subject
end
def workshop_facilitator_request(workshop, requester, message)
@workshop = Workshop.find(workshop) if workshop.present?
@requester = User.find(requester) if requester.present?
addresses = []
I18n.locale = @workshop.active_facilitators.first.locale if @workshop.active_facilitators.first.locale.present?
@workshop.active_facilitators.each do |f|
addresses << f.named_email
end
@message = message
@conference = Conference.find(@workshop.conference_id)
@subject = _('email.subject.workshop_facilitator_request',
"Request to facilitate #{@workshop.title} from #{@requester.name}",
:vars => {:workshop_title => @workshop.title, :requester_name => @requester.firstname})
mail to: addresses, reply_to: addresses + [@requester.named_email], subject: @subject
end
def workshop_facilitator_request_approved(workshop, user)
@workshop = Workshop.find(workshop) if workshop.present?
@conference = Conference.find(@workshop.conference_id)
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.locale.present?
@subject = (_'email.subject.workshop_request_approved',
"You have been added as a facilitator of #{@workshop.title}",
:vars => {:workshop_title => @workshop.title})
mail to: @user.named_email, subject: @subject
end
def workshop_facilitator_request_approved(workshop, user)
@workshop = Workshop.find(workshop) if workshop.present?
@conference = Conference.find(@workshop.conference_id)
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.locale.present?
@subject = (_'email.subject.workshop_request_approved',
"You have been added as a facilitator of #{@workshop.title}",
:vars => {:workshop_title => @workshop.title})
mail to: @user.named_email, subject: @subject
end
def workshop_facilitator_request_denied(workshop, user)
@workshop = Workshop.find(workshop) if workshop.present?
@conference = @workshop.conference
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.present? && @user.locale.present?
@subject = (_'email.subject.workshop_request_denied',
"Your request to facilitate #{@workshop.title} has been denied",
:vars => {:workshop_title => @workshop.title})
mail to: @user.named_email, subject: @subject
end
def workshop_facilitator_request_denied(workshop, user)
@workshop = Workshop.find(workshop) if workshop.present?
@conference = @workshop.conference
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.present? && @user.locale.present?
@subject = (_'email.subject.workshop_request_denied',
"Your request to facilitate #{@workshop.title} has been denied",
:vars => {:workshop_title => @workshop.title})
mail to: @user.named_email, subject: @subject
end
def workshop_translated(workshop, data, locale, user, translator)
@workshop = Workshop.find(workshop) if workshop.present?
@data = data
@locale = locale
@locale_name = language_name(locale)
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.present? && @user.locale.present?
@translator = User.find(translator) if translator.present?
@subject = (_'email.subject.workshop_translated',
"The #{@locale_name} translation for #{@workshop.title} has been modified",
vars: {language: @language_name, workshop_title: @workshop.title})
def workshop_translated(workshop, data, locale, user, translator)
@workshop = Workshop.find(workshop) if workshop.present?
@data = data
@locale = locale
@locale_name = language_name(locale)
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.present? && @user.locale.present?
@translator = User.find(translator) if translator.present?
@subject = (_'email.subject.workshop_translated',
"The #{@locale_name} translation for #{@workshop.title} has been modified",
vars: {language: @language_name, workshop_title: @workshop.title})
@wrapper_id = :full_width
@wrapper_id = :full_width
mail to: @user.named_email, subject: @subject
end
mail to: @user.named_email, subject: @subject
end
def workshop_original_content_changed(workshop, data, user, translator)
@workshop = Workshop.find(workshop) if workshop.present?
@data = data
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.present? && @user.locale.present?
@translator = User.find(translator) if translator.present?
@subject = (_'email.subject.workshop_original_content_changed',
"Original content for #{@workshop.title} has been modified",
vars: {workshop_title: @workshop.title})
@data.each do |field, values|
diff = Diffy::Diff.new(values[:old], values[:new])
@data[field][:diff] = {
text: diff.to_s(:text),
html: diff.to_s(:html)
}
end
def workshop_original_content_changed(workshop, data, user, translator)
@workshop = Workshop.find(workshop) if workshop.present?
@data = data
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.present? && @user.locale.present?
@translator = User.find(translator) if translator.present?
@subject = (_'email.subject.workshop_original_content_changed',
"Original content for #{@workshop.title} has been modified",
vars: {workshop_title: @workshop.title})
@data.each do |field, values|
diff = Diffy::Diff.new(values[:old], values[:new])
@data[field][:diff] = {
text: diff.to_s(:text),
html: diff.to_s(:html)
}
end
@wrapper_id = :full_width
@wrapper_id = :full_width
mail to: @user.named_email, subject: @subject
end
mail to: @user.named_email, subject: @subject
end
def workshop_comment(workshop, comment, user)
@workshop = Workshop.find(workshop) if workshop.present?
@comment = Comment.find(comment) if comment.present?
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.present? && @user.locale.present?
def workshop_comment(workshop, comment, user)
@workshop = Workshop.find(workshop) if workshop.present?
@comment = Comment.find(comment) if comment.present?
@user = User.find(user) if user.present?
I18n.locale = @user.locale if @user.present? && @user.locale.present?
if @comment.reply?
@subject = (_'email.subject.workshop_comment.reply', vars: { user_name: @comment.user.name })
else
@subject = (_'email.subject.workshop_comment.comment', vars: { user_name: @comment.user.name, workshop_title: @workshop.title })
end
if @comment.reply?
@subject = (_'email.subject.workshop_comment.reply', vars: { user_name: @comment.user.name })
else
@subject = (_'email.subject.workshop_comment.comment', vars: { user_name: @comment.user.name, workshop_title: @workshop.title })
end
mail to: @user.named_email, subject: @subject
end
mail to: @user.named_email, subject: @subject
end
def error_report(subject, message, report, exception, request, params, user, time = nil)
@subject = subject
@message = message
@report = report
@exception = exception
@request = request
@params = params
@time = time
@user = User.find(user) if user.present?
mail to: 'goodgodwin@hotmail.com', subject: @subject
end
def error_report(subject, message, report, exception, request, params, user, time = nil)
@subject = subject
@message = message
@report = report
@exception = exception
@request = request
@params = params
@time = time
@user = User.find(user) if user.present?
mail to: 'goodgodwin@hotmail.com', subject: @subject
end
def contact(from, subject, message, email_list)
@message = message
@subject = subject
@from = from.is_a?(Integer) ? User.find(from) : from
def contact(from, subject, message, email_list)
@message = message
@subject = subject
@from = from.is_a?(Integer) ? User.find(from) : from
mail to: email_list.join(', '), subject: @subject, reply_to: @from.is_a?(User) ? @from.named_email : @from
end
mail to: email_list.join(', '), subject: @subject, reply_to: @from.is_a?(User) ? @from.named_email : @from
end
def contact_details(from, subject, message, request, params)
@message = message
@subject = "Details for: \"#{subject}\""
@from = from.is_a?(Integer) ? User.find(from) : from
@request = request
@params = params
def contact_details(from, subject, message, request, params)
@message = message
@subject = "Details for: \"#{subject}\""
@from = from.is_a?(Integer) ? User.find(from) : from
@request = request
@params = params
mail to: 'goodgodwin@hotmail.com', subject: @subject
end
mail to: 'goodgodwin@hotmail.com', subject: @subject
end
private
def set_host(*args)
if Rails.env.production?
@host = "https://#{I18n.locale.to_s}.bikebike.org"
elsif Rails.env.preview?
@host = "https://preview-#{I18n.locale.to_s}.bikebike.org"
else
@host = UserMailer.default_url_options[:host]
end
end
private
def set_host(*args)
if Rails.env.production?
@host = "https://#{I18n.locale.to_s}.bikebike.org"
elsif Rails.env.preview?
@host = "https://preview-#{I18n.locale.to_s}.bikebike.org"
else
@host = UserMailer.default_url_options[:host]
end
end
end

77
app/models/city.rb Normal file
View File

@ -0,0 +1,77 @@
require 'geocoder'
require 'geocoder/railtie'
require 'geocoder/calculations'
Geocoder::Railtie.insert
class City < ActiveRecord::Base
geocoded_by :address
translates :city
reverse_geocoded_by :latitude, :longitude, :address => :full_address
after_validation :geocode, if: ->(obj){ obj.country_changed? or obj.territory_changed? or obj.city_changed? or obj.latitude.blank? or obj.longitude.blank? }
def address
([city!, territory, country] - [nil, '']).join(', ')
end
def get_translation(locale)
location = Geocoder.search(address, language: locale.to_s).first
location.data['address_components'].each do | component |
if component['types'].first == 'locality'
return component['short_name']
end
end
return nil
end
def translate_city(locale)
translation = get_translation(locale)
set_column_for_locale(:city, locale, translation)
save!
return translation
end
def self.search(str)
cache = CityCache.search(str)
# return the city if this search is in our cache
return cache.city if cache.present?
# look up the city in the geocoder
location = Geocoder.search(str, language: 'en').first
# see if the city is already present in our database
city = City.find_by_place_id(location.data['place_id'])
# return the city if we found it in the db already
return city if city.present?
# otherwise build a new city
component_alises = {
'locality' => :city,
'administrative_area_level_1' => :territory,
'country' => :country
}
city_data = {
locale: :en,
latitude: location.data['geometry']['location']['lat'],
longitude: location.data['geometry']['location']['lng'],
place_id: location.data['place_id']
}
location.data['address_components'].each do | component |
property = component_alises[component['types'].first]
city_data[property] = component['short_name'] if property.present?
end
# save the new city
city = City.new(city_data)
city.save!
# and return it
return city
end
end

9
app/models/city_cache.rb Normal file
View File

@ -0,0 +1,9 @@
class CityCache < ActiveRecord::Base
self.table_name = :city_cache
belongs_to :city
def self.search(str)
CityCache.find_by_search(str.downcase)
end
end

View File

@ -1,27 +1,27 @@
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :user
def comment_object
model_type.classify.constantize.find(model_id)
end
def comment_object
model_type.classify.constantize.find(model_id)
end
def set_model(model)
model_type = model.class.name.tableize
model_id = model.id
end
def set_model(model)
model_type = model.class.name.tableize
model_id = model.id
end
def self.for(model)
where(model_type: model.class.name.tableize, model_id: model.id).order(created_at: :asc)
end
def self.for(model)
where(model_type: model.class.name.tableize, model_id: model.id).order(created_at: :asc)
end
def self.create_for(model, user, comment)
create(
model_type: model.class.name.tableize,
model_id: model.id,
user_id: user.id,
comment: comment
)
end
def self.create_for(model, user, comment)
create(
model_type: model.class.name.tableize,
model_id: model.id,
user_id: user.id,
comment: comment
)
end
def add_comment(user, comment)
Comment.create_for(self, user, comment)
@ -32,6 +32,6 @@ class Comment < ActiveRecord::Base
end
def reply?
model_type == 'comments'
model_type == 'comments'
end
end

View File

@ -1,71 +1,136 @@
class Conference < ActiveRecord::Base
translates :info, :title, :payment_message
translates :info, :title, :payment_message
mount_uploader :cover, CoverUploader
mount_uploader :poster, PosterUploader
mount_uploader :cover, CoverUploader
mount_uploader :poster, PosterUploader
belongs_to :conference_type
belongs_to :conference_type
belongs_to :city
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
has_many :conference_host_organizations, dependent: :destroy
has_many :organizations, through: :conference_host_organizations
has_many :conference_administrators, dependent: :destroy
has_many :administrators, through: :conference_administrators, source: :user
has_many :event_locations
has_many :workshops
has_many :workshops
accepts_nested_attributes_for :conference_host_organizations, reject_if: proc {|u| u[:organization_id].blank?}, allow_destroy: true
accepts_nested_attributes_for :conference_host_organizations, :reject_if => proc {|u| u[:organization_id].blank?}, :allow_destroy => true
before_create :make_slug
def to_param
slug
end
def to_param
slug
end
def host?(user)
return false unless user.present?
organizations.each do |o|
return true if o.host?(user)
end
return false
end
def host_organization?(org)
return false unless org.present?
org_id = org.is_a?(Organization) ? org.id : org
def url(action = :show)
path(action)
end
organizations.each do |o|
return true if o.id = org_id
end
def path(action = :show)
action = action.to_sym
'/conferences/' + conference_type.slug + '/' + slug + (action == :show ? '' : '/' + action.to_s)
end
return false
end
def location
organizations.first.location
end
def host?(user)
if user.present?
return true if user.administrator?
conference_administrators.each do |u|
return true if user.id == u.id
end
organizations.each do |o|
return true if o.host?(user)
end
end
return false
end
def registered?(user)
registration = ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id)
return registration ? registration.is_attending : false
end
def url(action = :show)
path(action)
end
def registration_exists?(user)
ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id).present?
end
def path(action = :show)
action = action.to_sym
'/conferences/' + conference_type.slug + '/' + slug + (action == :show ? '' : '/' + action.to_s)
end
def registration_open
registration_status == :open
end
def location
return nil unless organizations.present?
organizations.first.location
end
def registration_status
s = read_attribute(:registration_status)
s.present? ? s.to_sym : nil
end
def registered?(user)
registration = ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id)
return registration ? registration.is_attending : false
end
def registration_status=(new_registration_status)
write_attribute :registration_status, new_registration_status.to_s
end
def registration_exists?(user)
ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id).present?
end
def self.default_payment_amounts
[25, 50, 100]
end
def registration_open
registration_status == :open
end
def registration_status
s = read_attribute(:registration_status)
s.present? ? s.to_sym : nil
end
def registration_status=(new_registration_status)
write_attribute :registration_status, new_registration_status.to_s
end
def make_slug(reset = false)
if reset
self.slug = nil
end
self.slug ||= Conference.generate_slug(
conferencetype || :annual,
conference_year,
city_name.gsub(/\s/, '')
)
end
def city_name
return city.city if city.present?
return location.present? ? location.city : nil
end
def conference_year
self.year || (end_date.present? ? end_date.year : nil)
end
def over?
return false unless end_date.present?
return end_date < DateTime.now
end
def self.default_payment_amounts
[25, 50, 100]
end
def self.conference_types
{
annual: '%{city}%{year}',
n: 'North%{year}',
s: 'South%{year}',
e: 'East%{year}',
w: 'West%{year}',
ne: 'Northeast%{year}',
nw: 'Northwest%{year}',
se: 'Southeast%{year}',
sw: 'Southwest%{year}'
}
end
def self.generate_slug(type, year, city)
Conference.conference_types[(type || :annual).to_sym].gsub('%{city}', city).gsub('%{year}', year.to_s)
end
end

View File

@ -0,0 +1,4 @@
class ConferenceAdministrator < ActiveRecord::Base
belongs_to :user
belongs_to :conference
end

View File

@ -1,58 +1,58 @@
class ConferenceRegistration < ActiveRecord::Base
belongs_to :conference
belongs_to :user
has_many :conference_registration_responses
belongs_to :conference
belongs_to :user
has_many :conference_registration_responses
AttendingOptions = [:yes, :no]
AttendingOptions = [:yes, :no]
def languages
user.languages
end
def languages
user.languages
end
def self.all_housing_options
[:none, :tent, :house]
end
def self.all_housing_options
[:none, :tent, :house]
end
def self.all_spaces
[:bed_space, :floor_space, :tent_space]
end
def self.all_spaces
[:bed_space, :floor_space, :tent_space]
end
def self.all_bike_options
[:yes, :no]
end
def self.all_bike_options
[:yes, :no]
end
def self.all_food_options
[:meat, :vegetarian, :vegan]
end
def self.all_food_options
[:meat, :vegetarian, :vegan]
end
def self.all_considerations
[:vegan, :smoking, :pets, :quiet]
end
def self.all_considerations
[:vegan, :smoking, :pets, :quiet]
end
def status(was = false)
return :unregistered if user.firstname.blank? || self.send(was ? :city_was : :city).blank?
return :registered if self.send(was ? :housing_was : :housing).present? || (self.send(was ? :can_provide_housing_was : :can_provide_housing) && (self.send(was ? :housing_data_was : :housing_data) || {})['availability'].present?)
return :preregistered
end
def status(was = false)
return :unregistered if user.nil? || user.firstname.blank? || self.send(was ? :city_was : :city).blank?
return :registered if self.send(was ? :housing_was : :housing).present? || (self.send(was ? :can_provide_housing_was : :can_provide_housing) && (self.send(was ? :housing_data_was : :housing_data) || {})['availability'].present?)
return :preregistered
end
around_update :check_status
around_update :check_status
def check_status
yield
old_status = status(true)
new_status = status
def check_status
yield
old_status = status(true)
new_status = status
if old_status.present? && old_status != new_status
if (conference.registration_status == :pre && new_status == :preregistered) ||
(conference.registration_status == :open && new_status == :registered)
if old_status.present? && old_status != new_status
if (conference.registration_status == :pre && new_status == :preregistered) ||
(conference.registration_status == :open && new_status == :registered)
UserMailer.send_mail :registration_confirmation do
{
:args => self
}
end
end
end
end
UserMailer.send_mail :registration_confirmation do
{
:args => self
}
end
end
end
end
end

View File

@ -1,20 +1,20 @@
class Event < ActiveRecord::Base
translates :info, :title
translates :info, :title
belongs_to :conference
belongs_to :event_location
belongs_to :conference
belongs_to :event_location
def conference_day
return nil unless start_time.present? && end_time.present?
def conference_day
return nil unless start_time.present? && end_time.present?
start_day = conference.start_date.change(hour: 0, minute: 0, second: 0)
w_start_day = start_time.change(hour: 0, minute: 0, second: 0)
return (((w_start_day - start_day) / 86400) + 1).to_i
end
start_day = conference.start_date.change(hour: 0, minute: 0, second: 0)
w_start_day = start_time.change(hour: 0, minute: 0, second: 0)
return (((w_start_day - start_day) / 86400) + 1).to_i
end
def duration
return nil unless start_time.present? && end_time.present?
((end_time - start_time) / 60).to_i
end
def duration
return nil unless start_time.present? && end_time.present?
((end_time - start_time) / 60).to_i
end
end

View File

@ -1,6 +1,6 @@
class LocationsOrganization < ActiveRecord::Base
belongs_to :location
belongs_to :organization
self.primary_key = :location_id
end
class LocationsOrganization < ActiveRecord::Base
belongs_to :location
belongs_to :organization
self.primary_key = :location_id
end

View File

@ -1,71 +1,77 @@
class Organization < ActiveRecord::Base
mount_uploader :logo, LogoUploader
mount_uploader :avatar, AvatarUploader
mount_uploader :cover, CoverUploader
mount_uploader :logo, LogoUploader
mount_uploader :avatar, AvatarUploader
mount_uploader :cover, CoverUploader
has_many :locations_organization
has_many :locations, :through => :locations_organization
has_many :locations_organization
has_many :locations, through: :locations_organization
has_many :user_organization_relationships, :dependent => :destroy
has_many :users, :through => :user_organization_relationships
has_many :user_organization_relationships, dependent: :destroy
has_many :users, through: :user_organization_relationships
accepts_nested_attributes_for :locations, :reject_if => proc {|l| l[id].blank?}
accepts_nested_attributes_for :user_organization_relationships, :reject_if => proc {|u| u[:user_id].blank?}, :allow_destroy => true
before_create :make_slug
accepts_nested_attributes_for :locations, :reject_if => proc {|l| l[id].blank?}
accepts_nested_attributes_for :user_organization_relationships, :reject_if => proc {|u| u[:user_id].blank?}, :allow_destroy => true
before_create :make_slug
def location
locations.first
end
def location
locations.first
end
def longitude
location.longitude
end
def longitude
location.longitude
end
def latitude
location.latitude
end
def latitude
location.latitude
end
def to_param
slug
end
def to_param
slug
end
def host?(user)
return false unless user.present?
return true if user.administrator?
users.each do |u|
return true if u.id == user.id
end
return false
end
def host?(user)
return false unless user.present?
return true if user.administrator?
users.each do |u|
return true if u.id == user.id
end
return false
end
def generate_slug(name, location = nil)
s = name.gsub(/[^a-z1-9]+/i, '-').chomp('-').gsub(/\-([A-Z])/, '\1')
if Organization.find_by(:slug => s).present? && !location.nil?
if location.city.present?
s += '-' + location.city
end
if Organization.find_by(:slug => s).present? && location.territory.present?
s += '-' + location.territory
end
if Organization.find_by(:slug => s).present?
s += '-' + location.country
end
end
attempt = 1
ss = s
def generate_slug(name, location = nil)
s = name.gsub(/[^a-z1-9]+/i, '-').chomp('-').gsub(/\-([A-Z])/, '\1')
if Organization.find_by(:slug => s).present? && !location.nil?
if location.city.present?
s += '-' + location.city
end
if Organization.find_by(:slug => s).present? && location.territory.present?
s += '-' + location.territory
end
if Organization.find_by(:slug => s).present?
s += '-' + location.country
end
end
attempt = 1
ss = s
while Organization.find_by(:slug => s)
attempt += 1
s = ss + '-' + attempt.to_s
end
s
end
while Organization.find_by(:slug => s)
attempt += 1
s = ss + '-' + attempt.to_s
end
s
end
private
def make_slug
if !self.slug
self.slug = generate_slug(self.name, self.locations && self.locations[0])
end
end
def self.find_by_city(city)
Organization.joins(:locations).where(locations: {
city_id: city.is_a?(City) ? city.id : city
})
end
private
def make_slug
if !self.slug
self.slug = generate_slug(self.name, self.locations && self.locations[0])
end
end
end

View File

@ -1,62 +1,67 @@
class User < ActiveRecord::Base
authenticates_with_sorcery! do |config|
authenticates_with_sorcery! do |config|
config.authentications_class = Authentication
end
validates :email, uniqueness: true
validates :email, uniqueness: true
mount_uploader :avatar, AvatarUploader
mount_uploader :avatar, AvatarUploader
has_many :user_organization_relationships
has_many :organizations, through: :user_organization_relationships
has_many :authentications, :dependent => :destroy
accepts_nested_attributes_for :authentications
has_many :user_organization_relationships
has_many :organizations, through: :user_organization_relationships
has_many :conferences, through: :conference_administrators
has_many :authentications, :dependent => :destroy
accepts_nested_attributes_for :authentications
before_update do |user|
user.locale ||= I18n.locale
end
before_update do |user|
user.locale ||= I18n.locale
end
before_save do |user|
user.locale ||= I18n.locale
end
before_save do |user|
user.locale ||= I18n.locale
end
def can_translate?(to_locale = nil, from_locale = nil)
is_translator unless to_locale.present?
def can_translate?(to_locale = nil, from_locale = nil)
is_translator unless to_locale.present?
from_locale = I18n.locale unless from_locale.present?
return languages.present? &&
to_locale.to_s != from_locale.to_s &&
languages.include?(to_locale.to_s) &&
languages.include?(from_locale.to_s)
end
from_locale = I18n.locale unless from_locale.present?
return languages.present? &&
to_locale.to_s != from_locale.to_s &&
languages.include?(to_locale.to_s) &&
languages.include?(from_locale.to_s)
end
def name
firstname || username || email
end
def name
firstname || username || email
end
def named_email
name = firstname || username
return email unless name
return "#{name} <#{email}>"
end
def named_email
name = firstname || username
return email unless name
return "#{name} <#{email}>"
end
def administrator?
role == 'administrator'
end
def administrator?
role == 'administrator'
end
def self.AVAILABLE_LANGUAGES
[:en, :es, :fr, :ar]
end
def self.AVAILABLE_LANGUAGES
[:en, :es, :fr, :ar]
end
def self.get(email)
user = where(email: email).first
def self.get(email)
user = where(email: email).first
unless user
user = new(email: email)
user.save!
end
unless user
user = new(email: email)
user.save!
end
return user
end
return user
end
def self.find_user(email)
User.where('lower(email) = ?', email.downcase).first
end
end

View File

@ -1,11 +1,11 @@
class UserOrganizationRelationship < ActiveRecord::Base
belongs_to :user
belongs_to :organization
Administrator = 'administrator'
Member = 'member'
DefaultRelationship = Member
AllRelationships = [Administrator, Member]
end
class UserOrganizationRelationship < ActiveRecord::Base
belongs_to :user
belongs_to :organization
Administrator = 'administrator'
Member = 'member'
DefaultRelationship = Member
AllRelationships = [Administrator, Member]
end

View File

@ -3,102 +3,102 @@ require 'carrierwave/processing/mini_magick'
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::ImageOptimizer
include CarrierWave::MiniMagick
include CarrierWave::ImageOptimizer
include CarrierWave::MiniMagick
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
# Choose what kind of storage to use for this uploader:
storage :file
process :optimize
storage :file
process :optimize
@@sizes = {:thumb => [120, 120], :icon => [48, 48], :preview => [360, 120], :normal => [512, 512]}
# storage :fog
@@sizes = {:thumb => [120, 120], :icon => [48, 48], :preview => [360, 120], :normal => [512, 512]}
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
#"/images/fallback/" + [version_name, "default.png"].compact.join('_')
"http://placehold.it/" + (@@sizes[version_name] || [300, 300]).join('x')
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
#"/images/fallback/" + [version_name, "default.png"].compact.join('_')
# "http://placehold.it/" + (@@sizes[version_name] || [300, 300]).join('x')
#end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
#def scale(width, height)
#end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
#def scale(width, height)
#end
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fill => @@sizes[:thumb]
end
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fill => @@sizes[:thumb]
end
version :icon do
process :resize_to_fill => @@sizes[:icon]
end
version :icon do
process :resize_to_fill => @@sizes[:icon]
end
version :preview do
process :resize_to_fit => @@sizes[:preview]
end
version :preview do
process :resize_to_fit => @@sizes[:preview]
end
version :normal do
process :resize_to_fit => @@sizes[:normal]
end
version :normal do
process :resize_to_fit => @@sizes[:normal]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
def image
@image ||= MiniMagick::Image.open(file.path)
end
def image
@image ||= MiniMagick::Image.open(file.path)
end
def is_landscape?
image['width'] > (image['height'] * 1.25)
end
def is_landscape?
image['width'] > (image['height'] * 1.25)
end
#def recreate_versions!(*versions)
# if !current_path.nil?
# current_path = "'" + (current_path || '') + "'"
# end
# super(*versions)
#end
#def recreate_versions!(*versions)
# if !current_path.nil?
# current_path = "'" + (current_path || '') + "'"
# end
# super(*versions)
#end
# def manipulate!
# cache_stored_file! if !cached?
# image = ::MiniMagick::Image.open(current_path)
# def manipulate!
# cache_stored_file! if !cached?
# image = ::MiniMagick::Image.open(current_path)
#
# begin
# image.format(@format.to_s.downcase) if @format
# image = yield(image)
# image.write(current_path)
# image.run_command("identify", '"' + current_path + '"')
# ensure
# image.destroy!
# end
# rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
# default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en)
# message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default)
# raise CarrierWave::ProcessingError, message
# end
# begin
# image.format(@format.to_s.downcase) if @format
# image = yield(image)
# image.write(current_path)
# image.run_command("identify", '"' + current_path + '"')
# ensure
# image.destroy!
# end
# rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
# default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en)
# message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default)
# raise CarrierWave::ProcessingError, message
# end
end

View File

@ -3,67 +3,67 @@ require 'carrierwave/processing/mini_magick'
class PosterUploader < CarrierWave::Uploader::Base
include CarrierWave::ImageOptimizer
include CarrierWave::MiniMagick
include CarrierWave::ImageOptimizer
include CarrierWave::MiniMagick
storage :file
process :optimize
storage :file
process :optimize
@@sizes = {
:thumb => [120, 120],
:icon => [48, 48],
:preview => [512, 512],
:full => [1024, 1024]
}
@@sizes = {
:thumb => [120, 120],
:icon => [48, 48],
:preview => [512, 512],
:full => [1024, 1024]
}
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process :resize_to_fill => @@sizes[:thumb]
end
version :thumb do
process :resize_to_fill => @@sizes[:thumb]
end
version :icon do
process :resize_to_fill => @@sizes[:icon]
end
version :icon do
process :resize_to_fill => @@sizes[:icon]
end
version :preview do
process :resize_to_fit => @@sizes[:preview]
end
version :preview do
process :resize_to_fit => @@sizes[:preview]
end
version :full do
process :resize_to_fit => @@sizes[:full]
end
version :full do
process :resize_to_fit => @@sizes[:full]
end
def image
@image ||= MiniMagick::Image.open(file.path)
end
def image
@image ||= MiniMagick::Image.open(file.path)
end
def is_landscape?
image['width'] > image['height']
end
def is_landscape?
image['width'] > image['height']
end
def manipulate!
cache_stored_file! if !cached?
image = ::MiniMagick::Image.open(current_path)
def manipulate!
cache_stored_file! if !cached?
image = ::MiniMagick::Image.open(current_path)
begin
image.format(@format.to_s.downcase) if @format
image = yield(image)
image.write(current_path)
begin
image.run_command("identify", current_path)
rescue
image.run_command("identify", '"' + current_path + '"')
end
ensure
image.destroy!
end
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en)
message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default)
raise CarrierWave::ProcessingError, message
end
begin
image.format(@format.to_s.downcase) if @format
image = yield(image)
image.write(current_path)
begin
image.run_command("identify", current_path)
rescue
image.run_command("identify", '"' + current_path + '"')
end
ensure
image.destroy!
end
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en)
message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default)
raise CarrierWave::ProcessingError, message
end
end

View File

@ -0,0 +1,24 @@
- body_class 'banner-bottom'
= render :partial => 'application/header', :locals => {:page_group => :administration, :page_key => 'Administration', :image_file => 'admin.jpg'}
%article
= row do
= form_tag save_conference_path, class: 'composition' do
= columns(medium: 12) do
%h2=_@page_title, :t
= hidden_field_tag :id, @this_conference.id if @this_conference.id.present?
= columns(medium: 12) do
= textfield :city, location(@this_conference.city), required: true, big: true
= columns(medium: 12, class: 'flex-column') do
= selectfield :type, @this_conference.conferencetype, Conference.conference_types.keys.map { |k| [(_"forms.options.conferences.types.#{k}"), k]}, required: true, stretch: true
= numberfield :year, @this_conference.conference_year || Date.today.year, required: true
= columns(medium: 6) do
= checkbox :is_public, @this_conference.is_public != false, 'forms.labels.generic.is_public'
= columns(medium: 6) do
= checkbox :is_featured, @this_conference.is_featured != false, 'forms.labels.generic.is_featured'
= columns(medium: 12) do
.actions.next-prev
= button_tag :save, value: :save
- if @this_conference.id.present?
= button_with_confirmation :delete, value: :delete, class: 'delete'

View File

@ -1,20 +1,20 @@
- content_for :banner do
- image = image_path(image_file || 'empty-racks.jpg')
- style = nil
- cover = nil
- figure = nil
- if capable_of(:css_mixblendmode)
- cover = "<div class=\"cover\" style=\"background-image: url(#{image})\"></div>"
- else
- style = "background-image: url(#{image})"
#header-title.short{style: style}
= (render banner_image, {:image => image}) if defined?(banner_image) == "local-variable"
= cover.html_safe if cover
- if @page_title.present? || defined?(page_group)
- content_for :title do
=@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}", :t, @main_title_vars)
- content_for :og_image do
= image
- image = image_path(image_file || 'empty-racks.jpg')
- style = nil
- cover = nil
- figure = nil
- if capable_of(:css_mixblendmode)
- cover = "<div class=\"cover\" style=\"background-image: url(#{image})\"></div>"
- else
- style = "background-image: url(#{image})"
#header-title.short{style: style}
= (render banner_image, {:image => image}) if defined?(banner_image) == "local-variable"
= cover.html_safe if cover
- if @page_title.present? || defined?(page_group)
- content_for :title do
= I18n.t(@page_title || "page_titles.#{page_group.to_s}.#{page_key.to_s}", @page_title_vars)
= row do
= columns do
%h1=_(@main_title || "page_titles.#{page_group.to_s}.#{page_key.to_s}", :t, @main_title_vars || (@page_title_vars.present? && @page_title.blank? ? { vars: @page_title_vars } : nil))
- content_for :og_image do
= image

View File

@ -1,17 +1,5 @@
- this_is_the_front_page
- if @conference
= render 'conferences/header'
%article
= row do
= columns(medium: 10, push: {medium: 1}) do
%h2=_!@conference.title
= richtext @conference.info
- if @conference.registration_status == :open
- if @conference.workshop_schedule_published
- add_inline_script :home_schedule
%h3=_'articles.workshops.headings.Schedule'
= render 'conferences/admin/schedule'
- else
%h3=_'articles.workshops.headings.Proposed_Workshops'
%p=_'articles.workshops.paragraphs.Proposed_Workshops'
= render 'workshops/workshop_previews', :workshops => (@conference.workshops.sort { |a, b| a.title.downcase <=> b.title.downcase })
- content_for :og_image do
= @conference.poster.full.url || image_path('default_poster.jpg')
- if @conferences
- @conferences.each do | conference |
= render 'conferences/conference', conference: conference, links: [ :read_more, :register ]

View File

@ -1,25 +1,25 @@
= render :partial => 'application/header', :locals => {:image_file => @banner_image || 'grafitti.jpg'}
%article
= row do
= columns do
- if logged_in?
%h2=_'articles.user_settings.headings.Your_Account'
- if @conference.present? && (@conference.registration_status == :pre || @conference.registration_status == :open)
%p=_'articles.user_settings.paragraphs.conference_registration', :t
= link_to (_'actions.conference.edit_registration'), register_path(@conference.slug), class: :button
- if @conferences.present?
%h3=_'articles.user_settings.headings.Your_Conferences'
.link-dump
- @conferences.each do | conference |
= link_to (_!conference.title), administration_step_path(conference.slug, :edit), class: :button
= row do
= columns do
- if logged_in?
%h2=_'articles.user_settings.headings.Your_Account'
- if @conference.present? && (@conference.registration_status == :pre || @conference.registration_status == :open)
%p=_'articles.user_settings.paragraphs.conference_registration', :t
= link_to (_'actions.conference.edit_registration'), register_path(@conference.slug), class: :button
- if @conferences.present?
%h3=_'articles.user_settings.headings.Your_Conferences'
.link-dump
- @conferences.each do | conference |
= link_to (_!conference.title), administration_step_path(conference.slug, :edit), class: :button
= form_tag update_settings_path do
= textfield :name, current_user.name, required: true, heading: 'articles.conference_registration.headings.name', big: true
= checkboxes :languages, User.AVAILABLE_LANGUAGES, current_user.languages || [I18n.locale], 'languages', heading: 'articles.conference_registration.headings.languages'
= radiobuttons :preferred_language, I18n.backend.enabled_locales, current_user.locale || I18n.locale, 'languages', heading: 'articles.conference_registration.headings.preferred_language'
= checkbox :email_subscribe, current_user.is_subscribed != false, 'articles.user_settings.email_subscribe', heading: 'articles.user_settings.headings.email_subscribe', help: 'articles.user_settings.paragraphs.email_subscribe', inline: true, right_help: true
.actions
= button_tag :save, value: :save
- else
%h2=_'forms.actions.generic.login'
= render 'login'
= form_tag update_settings_path do
= textfield :name, current_user.name, required: true, heading: 'articles.conference_registration.headings.name', big: true
= checkboxes :languages, User.AVAILABLE_LANGUAGES, current_user.languages || [I18n.locale], 'languages', heading: 'articles.conference_registration.headings.languages'
= radiobuttons :preferred_language, I18n.backend.enabled_locales, current_user.locale || I18n.locale, 'languages', heading: 'articles.conference_registration.headings.preferred_language'
= checkbox :email_subscribe, current_user.is_subscribed != false, 'articles.user_settings.email_subscribe', heading: 'articles.user_settings.headings.email_subscribe', help: 'articles.user_settings.paragraphs.email_subscribe', inline: true, right_help: true
.actions
= button_tag :save, value: :save
- else
%h2=_'forms.actions.generic.login'
= render 'login'

View File

@ -0,0 +1,41 @@
= columns(large: 8, push: { large: 2}) do
%h3=_'articles.admin.info.headings.Host_Organizations'
%p=_'articles.admin.info.descriptions.Host_Organizations', vars: { city_name: @this_conference.city.city }
= admin_update_form do
= checkboxes :organizations, (@organizations.map { |org| [org.name, org.id] }), @this_conference.organizations.map(&:id), 'test.test', vertical: true, big: true
.actions.right.small
= button_tag :save, value: :set_organizations
- @this_conference.organizations.each do | organization |
%h4=organization.name
- if organization.users.present?
.details.org-members
- organization.users.each do | user |
= raw_data_set(:h5, user.name) do
= user.email
- unless user.id == current_user.id && !current_user.administrator?
= admin_update_form class: [:inline, :right] do
= hidden_field_tag :user_id, user.id
= hidden_field_tag :org_id, organization.id
= button_tag :remove_member, value: :remove_org_member, class: [:small, :delete]
= admin_update_form class: 'mini-flex-form' do
= hidden_field_tag :org_id, organization.id
= emailfield :email, nil, required: true
= button_tag :add_member, value: :add_org_member, class: :small
%h3=_'articles.admin.info.headings.External_Administrators'
%p=_'articles.admin.info.descriptions.External_Administrators'
- if @this_conference.administrators.present?
.details.org-members
- @this_conference.administrators.each do | user |
= raw_data_set(:h5, user.name) do
= user.email
- unless user.id == current_user.id && !current_user.administrator?
= admin_update_form class: [:inline, :right] do
= hidden_field_tag :user_id, user.id
= button_tag :remove_member, value: :remove_administrator, class: [:small, :delete]
= admin_update_form class: 'mini-flex-form' do
= userfield :email, nil, required: true
-#= emailfield :email, nil, required: true
= button_tag :add_member, value: :add_administrator, class: :small
= columns(large: 2) do
&nbsp;

View File

@ -0,0 +1,23 @@
= columns(medium: 12) do
= admin_update_form do
- if @broadcast_step == :preview || @broadcast_step == :test
= hidden_field_tag :subject, @subject
= hidden_field_tag :body, @body
= hidden_field_tag :send_to, @send_to
- if @broadcast_step == :preview
%p= _'articles.conference_registration.paragraphs.admin.broadcast.test', vars: { send_to_count: "<strong>#{(@send_to_count || 0)}</strong>".html_safe }
- else
.warning-info.make-room= _'articles.conference_registration.paragraphs.admin.broadcast.preview', vars: { send_to_count: "<strong>#{(@send_to_count || 0)}</strong>".html_safe }
.test-preview
%h3=@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: "<strong>#{(@send_to_count || 0)}</strong>".html_safe }), value: :send, class: :delete if @broadcast_step == :test
= button_tag :edit, value: :edit
- else
= selectfield :send_to, nil, broadcast_options, full: true
= textfield :subject, @subject, required: true, big: true
= textarea :body, @body, lang: @this_conference.locale, edit_on: :focus
.actions.right
= button_tag :preview, value: :preview

View File

@ -0,0 +1,17 @@
= admin_update_form do
= row do
= columns(medium: 6, push: { medium: 1 }) do
= fieldset :start_date, inline: true, inline_label: true do
= month_select @start_month, name: :start_month, label: false
= month_day_select @start_day, name: :start_day, label: false
= row do
= columns(medium: 6, push: { medium: 1 }) do
= fieldset :end_date, inline: true, inline_label: true do
= month_select @end_month, name: :end_month, label: false
= month_day_select @end_day, name: :end_day, label: false
= row do
= columns(medium: 6, push: { medium: 1 }) do
.actions
= button_tag :save, value: :save

View File

@ -0,0 +1,5 @@
= columns(medium: 12) do
= admin_update_form do
= translate_textarea :info, @this_conference, label: 'articles.conference_registration.headings.admin.edit.info', help: 'articles.conference_registration.paragraphs.admin.edit.info', edit_on: :focus
.actions.right
= button_tag :save, value: :save

View File

@ -0,0 +1,41 @@
- if @this_conference.event_locations.blank?
= columns(medium: 12) do
.warning-info=_'articles.admin.events.no_locations_warning'
- else
= columns(medium: 12) do
- if @events.present? && @event.id.blank?
%table.events.admin-edit
%tr
%th=_'forms.labels.generic.title'
%th=_'forms.labels.generic.event_location'
%th=_'forms.labels.generic.day'
%th=_'forms.labels.generic.time'
%th=_'forms.labels.generic.time_span'
%th.form
- @events.each do | event |
%tr
%th=event.title
%td=_!(event.event_location.present? ? event.event_location.title : '')
%td=date(event.start_time.to_date, :weekday)
%td=time(event.start_time, :short)
%td=hours(event.start_time, event.end_time)
%td.form
= admin_update_form do
= hidden_field_tag :id, event.id
= link_to (_'forms.actions.generic.edit'), edit_event_path(@this_conference, event.id), class: [:button, :small, :modify]
= button_with_confirmation :delete, (_'modals.admin.generic.delete.confirm', :p, vars: { title: event.title }), value: :delete, class: [:delete, :small]
= columns(medium: 12) do
%h3=_"articles.admin.locations.headings.#{@event.id.present? ? 'edit' : 'add'}_event", :t
= admin_update_form do
= hidden_field_tag :id, @event.id if @event.id.present?
.flex-inputs
= location_select @event.event_location_id, small: true, stretch: true
= day_select @day, small: true, format: :weekday
= hour_select @time, small: true
= length_select @length, small: true
= translate_fields @event, { title: { type: :textfield, big: true, label: 'forms.labels.generic.title' }, info: { type: :textarea, 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?

View File

@ -0,0 +1,11 @@
.guests-housed
%h5 Guests Housed:
.data="#{@guests_housed} / #{@guests.size}"
%table.hosts.admin-edit
- @hosts.each do | id, registration |
%tr.host
%th
.name=registration.user.name
.address=registration.housing_data['address']
%td.inner-table{colspan: 2}=host_guests_table(registration)

View File

@ -0,0 +1,10 @@
- add_inline_script :housing
= columns(medium: 12) do
= admin_update_form id: 'housing-table-form' do
#housing-table= render partial: 'hosts_table'
#guest-selector
= admin_update_form class: 'guest-dlg', id: 'guest-list-table' do
%h3 Select a Guest
#table
.actions
= link_to (_'links.download.Excel'), administration_step_path(@this_conference.slug, @admin_step, :format => :xlsx), class: [:button, :download]

View File

@ -0,0 +1,42 @@
- unless @location.present?
- if @locations.present?
= columns(medium: 12) do
%table.locations.admin-edit
%tr
%th=_'forms.labels.generic.title'
%th=_'forms.labels.generic.address'
%th=_'articles.workshops.headings.space'
%th=_'articles.admin.locations.headings.amenities'
%th.form
- @locations.each do | location |
%tr
%th=_!(location.title || '')
%td=location_link location
%td=location.space.present? ? (_"workshop.options.space.#{location.space}") : ''
%td
- amenities = location.amenities.present? ? JSON.parse(location.amenities) : []
=_!(amenities.collect { |amenity| _"workshop.options.needs.#{amenity}" }).join(', ')
%td.form
= admin_update_form do
= hidden_field_tag :id, location.id
= link_to (_'forms.actions.generic.edit'), edit_location_path(@this_conference, location.id), class: [:button, :small, :modify]
= button_with_confirmation :delete, (_'modals.admin.generic.delete.confirm', :p, vars: { title: location.title }), value: :delete, class: [:delete, :small]
= admin_update_form do
= columns(medium: 12) do
%h5=_"articles.admin.locations.headings.#{@location.present? ? 'edit' : 'add'}_location", :t
= hidden_field_tag :id, @location.id if @location.present?
= textfield :title, @location.present? ? @location.title : nil, required: true, big: true, help: 'articles.admin.locations.paragraphs.title'
.flex-column.address-form
= textfield :address, @location.present? ? @location.address : nil, required: true, help: 'articles.admin.locations.paragraphs.address', stretch: true
.city=location(@this_conference.city)
= columns(medium: 6) do
= radiobuttons :space, EventLocation.all_spaces, @space, 'workshop.options.space', vertical: true, heading: 'articles.workshops.headings.space', required: true, help: 'articles.admin.locations.paragraphs.space'
= columns(medium: 6) do
= checkboxes :needs, EventLocation.all_amenities, @amenities || [], 'workshop.options.needs', vertical: true, heading: 'articles.admin.locations.headings.amenities', help: 'articles.admin.locations.paragraphs.amenities'
= columns(medium: 12) do
.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

View File

@ -0,0 +1,35 @@
= columns(medium: 12) do
- if @this_conference.event_locations.present?
- if @this_conference.meals.present?
%table.meals.admin-edit
%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
- @meals.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
= admin_update_form do
= hidden_field_tag :meal, time
= button_tag :delete, value: :delete, class: [:small, :delete]
= admin_update_form do
%h3=_'articles.admin.locations.headings.add_meal', :t
.flex-inputs
= location_select nil, small: true, stretch: true
= day_select nil, small: true, format: :weekday
= hour_select nil, small: true
= textfield :title, nil, required: true, big: true, help: 'articles.admin.locations.paragraphs.meal_title'
= textfield :info, nil, help: 'articles.admin.locations.paragraphs.meal_info'
.actions.next-prev
= button_tag :add_meal, value: :add_meal
- else
.warning-info=_'articles.admin.meals.no_locations_warning'

View File

@ -0,0 +1,6 @@
= columns(medium: 12) do
= form_tag administration_update_path(@this_conference.slug, @admin_step) do
= translate_textarea :payment_message, @this_conference, default: 'articles.conference_registration.paragraphs.Payment', help: 'articles.conference_registration.paragraphs.admin.payment.message', edit_on: :focus, short: true
.actions.right
= button_tag :save, value: :save

View File

@ -0,0 +1,8 @@
= columns(medium: 12) do
= form_tag administration_update_path(@this_conference.slug, @admin_step) do
= emailfield :paypal_email_address, @this_conference.paypal_email_address || @this_conference.email_address || (@this_conference.organizations.present? && @this_conference.organizations.first.present? ? @this_conference.organizations.first.email_address : nil)
= textfield :paypal_username, @this_conference.paypal_username
= passwordfield :paypal_password, @this_conference.paypal_password
= textfield :paypal_signature, @this_conference.paypal_signature
.actions.right
= button_tag :save, value: :save

View File

@ -0,0 +1,5 @@
= columns(medium: 12) do
= form_tag administration_update_path(@this_conference.slug, :poster), multipart: true do
= filefield :poster, @this_conference.poster, required: true, label: false, preview: true
.actions.left
= button_tag :upload, value: :upload, id: 'upload-file'

View File

@ -0,0 +1,2 @@
= columns(medium: 12) do
TO COME

View File

@ -0,0 +1,8 @@
= columns(medium: 12) do
= form_tag administration_update_path(@this_conference.slug, @admin_step) do
- if @this_conference.workshop_schedule_published
%p=_'articles.conference_registration.paragraphs.admin.schedule.published', :p
.actions= button_tag :un_publish, value: :publish, class: :delete
- else
%p=_'articles.conference_registration.paragraphs.admin.schedule.un_published', :p
.actions= button_tag :publish, value: :publish

View File

@ -0,0 +1,5 @@
= columns(medium: 12) do
= form_tag administration_update_path(@this_conference.slug, @admin_step) do
= selectfield :registration_status, @this_conference.registration_status || 'closed', registration_status_options_list, inline_label: true
.actions.left
= button_tag :save, value: :save

View File

@ -0,0 +1,17 @@
- add_inline_script :registrations
= columns(medium: 12) do
.goes-fullscreen#registrations-table
.flex-column
= searchfield :search, nil, big: true, stretch: true
%a.button{data: { expands: 'registrations-table' }}='expand'
%a.button.delete{data: { contracts: 'registrations-table' }}='close'
%a.button.modify{data: { 'opens-modal': 'new-registration' }}='+'
.table-scroller
= html_table @excel_data, registrations_table_options
= admin_update_form id: 'new-registration', class: 'modal-edit' do
.modal-edit-overlay{data: { 'closes-modal': 'new-registration' }}
.modal-edit-content
= html_edit_table @excel_data, registrations_edit_table_options
.actions.right
%a.button.subdued{data: { 'closes-modal': 'new-registration' }}='Cancel'
= button_tag :save, value: :save, class: :modify

View File

@ -0,0 +1,85 @@
= columns(medium: 12) do
- conference = @this_conference || @conference
- if conference.event_locations.blank? && @entire_page
.warning-info=_'articles.admin.schedule.no_locations_warning'
- else
- add_inline_script :schedule if @entire_page
#schedule-preview
- @schedule.each do | day, data |
%h4=date(day, :weekday)
%table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]}
- if data[:locations].present? && data[:locations].values.first != :add
%thead
%tr
%th.corner
- data[:locations].each do | id, location |
%th=location.is_a?(Symbol) ? '' : location.title
%tbody
- data[:times].each do | time, time_data |
%tr
- rowspan = (time_data[:length] * 2).to_i
%th=time(time)
- if time_data[:type] == :workshop
- data[:locations].each do | id, location |
- if time_data[:item][:workshops][id].present?
- workshop = time_data[:item][:workshops][id][:workshop]
- status = time_data[:item][:workshops][id][:status]
- else
- workshop = status = nil
%td{class: [time_data[:type], workshop.present? ? :filled : :open], rowspan: rowspan, data: workshop.present? ? nil : { block: time_data[:item][:block], day: day, location: id }}
- if workshop.present? && workshop.event_location.present?
= link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do
.details
.title=workshop.title
%template.event-details{data: { href: view_workshop_path(@conference.slug, workshop.id) }}
%h1.title=workshop.title
%p.address
= workshop.event_location.title + _!(': ')
= location_link workshop.event_location
.workshop-description= richtext workshop.info, 1
- if @can_edit
= form_tag administration_update_path(conference.slug, @admin_step), class: 'deschedule-workshop' do
.status
.conflict-score
%span.title Conflicts:
%span.value="#{status[:conflict_score]} / #{workshop.interested.size}"
- if status[:errors].present?
.errors
- status[:errors].each do | error |
.error=_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars]
= hidden_field_tag :id, workshop.id
= button_tag :deschedule, value: :deschedule_workshop, class: [:delete, :small]
- elsif @can_edit
.title="Block #{time_data[:item][:block] + 1}"
- elsif time_data[:type] != :nil
%td{class: time_data[:type], rowspan: rowspan, colspan: data[:locations].present? ? data[:locations].size : 1}
- case time_data[:type]
- when :meal
- location = EventLocation.where(id: time_data[:item]['location'].to_i).first
- if location.present?
%a.event-detail-link
.details
.title= time_data[:item]['title']
.location= location.title
%template.event-details
%h1.title=time_data[:item]['title']
%p.address
= location.title + _!(': ')
= location_link location
- when :event
- if time_data[:item].event_location.present?
%a.event-detail-link
.details
.title= time_data[:item][:title]
.location= time_data[:item].event_location.title
%template.event-details
%h1.title=time_data[:item][:title]
%p.address
= time_data[:item].event_location.title + _!(': ')
= location_link time_data[:item].event_location
= richtext time_data[:item][:info], 1
- if @entire_page
#workshop-selector
= form_tag administration_update_path(@this_conference.slug, @admin_step), class: 'workshop-dlg', id: 'workshop-table-form' do
%h3 Select a Workshop
#table

View File

@ -0,0 +1,46 @@
= hidden_field_tag :host, host.id
.host-field
%h4.inline=_'forms.labels.generic.name'
%span.plain-value= host.user.name
.host-field
%h4.inline=_'articles.conference_registration.headings.host.availability'
%span.plain-value= host.housing_data['availability'].present? && host.housing_data['availability'][1].present? ? date_span(host.housing_data['availability'][0].to_date, host.housing_data['availability'][1].to_date) : ''
- if host.housing_data['considerations'].present?
.host-field
%h4.inline=_'articles.conference_registration.headings.host.considerations'
%span.plain-value= (host.housing_data['considerations'].map { | consideration | _"articles.conference_registration.host.considerations.#{consideration}" }).join(', ')
- if sanitize(host.housing_data['notes'], tags: []).present?
.host-field
%h4=_'articles.conference_registration.headings.host.notes'
%blockquote= host.housing_data['notes'].html_safe
%table.guests.admin-edit
%tr
%th.corner
%th=_'forms.labels.generic.city'
%th=_'forms.labels.generic.housing'
%th=_'articles.admin.housing.headings.arrival_departure'
%th=_'articles.conference_registration.headings.companion'
%th=_'forms.labels.generic.food'
%th=_'forms.labels.generic.allergies'
%th=_'forms.labels.generic.other'
- @guests.each do | id, registration |
%tr.selectable{class: get_housing_match(host, registration, space).to_s.gsub('_', '-'), data: {host: host.id, guest: id, space: space}}
%th=registration.user.name
%td=registration.city
%td=registration.housing.present? ? (_"articles.conference_registration.questions.housing.#{registration.housing}") : ''
%td=date_span(registration.arrival.to_date, registration.departure.to_date)
- companion = companion(registration)
%td=companion.present? ? (companion.is_a?(User) ? companion.named_email : (_"articles.conference_registration.terms.registration_status.#{companion}")) : ''
%td=registration.food.present? ? (_"articles.conference_registration.questions.food.#{registration.food}") : ''
%td=registration.allergies
%td
.p=registration.other
.legend
%h4 Legend
%ul
%li.good-match Good Match
%li.bad-match Poor Match
%li.selected-space Also in this space
%li.other-space Also with this host
%li.other-host Already hosted

View File

@ -0,0 +1,21 @@
= columns(medium: 12) do
.details
= data_set(:h3, 'articles.admin.stats.headings.completed_registrations') do
= (@completed_registrations || 0).to_s
= data_set(:h3, 'articles.admin.stats.headings.incomplete_registrations') do
= ((@registration_count - @completed_registrations) || 0).to_s
= data_set(:h3, 'articles.admin.stats.headings.bikes') do
= (@completed_registrations || 0) > 0 ? "#{@bikes} (#{number_to_percentage(@bikes / @completed_registrations.to_f * 100.0)})" : "0"
= data_set(:h3, 'articles.admin.stats.headings.food.meat') do
= (@food[:all] || 0) > 0 ? "#{@food[:meat]} (#{number_to_percentage(@food[:meat] / @food[:all].to_f * 100.0)})" : "0"
= data_set(:h3, 'articles.admin.stats.headings.food.vegetarian') do
= (@food[:all] || 0) > 0 ? "#{@food[:vegetarian]} (#{number_to_percentage(@food[:vegetarian] / @food[:all].to_f * 100.0)})" : "0"
= data_set(:h3, 'articles.admin.stats.headings.food.vegan') do
= (@food[:all] || 0) > 0 ? "#{@food[:vegan]} (#{number_to_percentage(@food[:vegan] / @food[:all].to_f * 100.0)})" : "0"
= data_set(:h3, 'articles.admin.stats.headings.donation_count') do
= (@completed_registrations || 0) > 0 ? "#{@donation_count} (#{number_to_percentage(@donation_count / @completed_registrations.to_f * 100.0)})" : "0"
= data_set(:h3, 'articles.admin.stats.headings.donation_total') do
= "$#{@donations || 0.00}"
.actions
= link_to (_'links.download.Excel'), administration_step_path(@this_conference.slug, :stats, :format => :xlsx), class: [:button, :download]
= link_to (_'links.download.Organizations_Excel'), administration_step_path(@this_conference.slug, :organizations, :format => :xlsx), class: [:button, :download, :subdued]

View File

@ -0,0 +1,8 @@
= columns(medium: 12) do
= form_tag administration_update_path(@this_conference.slug, @admin_step) do
= fieldset :payment_amounts, label: false do
- payment_amounts = @this_conference.payment_amounts.present? ? @this_conference.payment_amounts : Conference.default_payment_amounts
- for i in 1..5 do
= numberfield "payment_amounts[#{i - 1}]", payment_amounts[i - 1], step: 0.01, min: 0.00, label: false
.actions.right
= button_tag :save, value: :save

Some files were not shown because too many files have changed in this diff Show More