Added conference list page, administration tools, and re-designed conference administration
29
Rakefile
@ -1,6 +1,23 @@
|
|||||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
# 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.
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||||
|
|
||||||
require File.expand_path('../config/application', __FILE__)
|
require File.expand_path('../config/application', __FILE__)
|
||||||
|
|
||||||
BikeBike::Application.load_tasks
|
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
|
||||||
|
@ -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
After Width: | Height: | Size: 131 KiB |
1
app/assets/images/admin/administrators.svg
Normal 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 |
BIN
app/assets/images/admin/broadcast.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
1
app/assets/images/admin/broadcast.svg
Normal 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 |
BIN
app/assets/images/admin/dates.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
1
app/assets/images/admin/dates.svg
Normal 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 |
BIN
app/assets/images/admin/description.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
1
app/assets/images/admin/description.svg
Normal 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 |
BIN
app/assets/images/admin/events.png
Normal file
After Width: | Height: | Size: 28 KiB |
1
app/assets/images/admin/events.svg
Normal 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 |
BIN
app/assets/images/admin/housing.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
1
app/assets/images/admin/housing.svg
Normal 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 |
BIN
app/assets/images/admin/locations.png
Normal file
After Width: | Height: | Size: 20 KiB |
1
app/assets/images/admin/locations.svg
Normal 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 |
BIN
app/assets/images/admin/meals.png
Normal file
After Width: | Height: | Size: 22 KiB |
1
app/assets/images/admin/meals.svg
Normal 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 |
BIN
app/assets/images/admin/payment.png
Normal file
After Width: | Height: | Size: 20 KiB |
1
app/assets/images/admin/payment.svg
Normal 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 |
1
app/assets/images/admin/payment_message.svg
Normal 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 |
1
app/assets/images/admin/paypal.svg
Normal 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 |
BIN
app/assets/images/admin/poster.png
Normal file
After Width: | Height: | Size: 11 KiB |
1
app/assets/images/admin/poster.svg
Normal 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 |
BIN
app/assets/images/admin/providers.png
Normal file
After Width: | Height: | Size: 20 KiB |
1
app/assets/images/admin/providers.svg
Normal 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 |
1
app/assets/images/admin/publish_schedule.svg
Normal 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 |
1
app/assets/images/admin/registration_status.svg
Normal 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 |
BIN
app/assets/images/admin/registrations.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
1
app/assets/images/admin/registrations.svg
Normal 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 |
BIN
app/assets/images/admin/schedule.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
1
app/assets/images/admin/schedule.svg
Normal 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 |
BIN
app/assets/images/admin/stats.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
1
app/assets/images/admin/stats.svg
Normal 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 |
1
app/assets/images/admin/suggested_amounts.svg
Normal 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 |
BIN
app/assets/images/admin/workshop_times.png
Normal file
After Width: | Height: | Size: 18 KiB |
1
app/assets/images/admin/workshop_times.svg
Normal 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 |
BIN
app/assets/images/conferences.jpg
Normal file
After Width: | Height: | Size: 858 KiB |
Before Width: | Height: | Size: 308 B After Width: | Height: | Size: 308 B |
1
app/assets/images/facebook.svg
Normal 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 |
Before Width: | Height: | Size: 470 B After Width: | Height: | Size: 470 B |
1
app/assets/images/github.svg
Normal 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 |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@ -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>
|
</svg>
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@ -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 |
@ -1,115 +1,130 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var pens = {};
|
var pens = {};
|
||||||
|
|
||||||
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(editor) {
|
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(editor) {
|
||||||
var event= editor.dataset.editOn;
|
var event= editor.dataset.editOn;
|
||||||
if (event == 'load') {
|
if (event == 'load') {
|
||||||
startEditing(editor);
|
startEditing(editor);
|
||||||
} else {
|
} else {
|
||||||
editor.addEventListener(event, function() {
|
editor.addEventListener(event, function() {
|
||||||
if (editor.getAttribute('contenteditable') !== 'true') {
|
if (editor.getAttribute('contenteditable') !== 'true') {
|
||||||
startEditing(editor);
|
startEditing(editor);
|
||||||
// for content editable, we need to refocus to show the caret
|
// for content editable, we need to refocus to show the caret
|
||||||
editor.blur();
|
editor.blur();
|
||||||
editor.focus();
|
editor.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function startEditing(editor) {
|
function startEditing(editor) {
|
||||||
var name = editor.dataset.name;
|
var name = editor.dataset.name;
|
||||||
pens[name] = new Pen({
|
pens[name] = new Pen({
|
||||||
editor: editor,
|
editor: editor,
|
||||||
class: 'pen',
|
class: 'pen',
|
||||||
textarea: '<textarea name="' + name + '"></textarea>',
|
textarea: '<textarea name="' + name + '"></textarea>',
|
||||||
list: ['p', 'h1', 'h2', 'blockquote', 'insertorderedlist', 'insertunorderedlist', 'bold', 'italic', 'underline', 'strikethrough', 'createlink', 'insertimage'],
|
list: ['p', 'h1', 'h2', 'blockquote', 'insertorderedlist', 'insertunorderedlist', 'bold', 'italic', 'underline', 'strikethrough', 'createlink', 'insertimage'],
|
||||||
title: {
|
title: {
|
||||||
'p': 'Paragraph',
|
'p': 'Paragraph',
|
||||||
'h1': 'Major Heading',
|
'h1': 'Major Heading',
|
||||||
'h2': 'Minor Heading',
|
'h2': 'Minor Heading',
|
||||||
'blockquote': 'Quotation',
|
'blockquote': 'Quotation',
|
||||||
'insertorderedlist': 'Ordered List',
|
'insertorderedlist': 'Ordered List',
|
||||||
'insertunorderedlist': 'Unordered List',
|
'insertunorderedlist': 'Unordered List',
|
||||||
'bold': 'Bold',
|
'bold': 'Bold',
|
||||||
'italic': 'Italic',
|
'italic': 'Italic',
|
||||||
'underline': 'Underline',
|
'underline': 'Underline',
|
||||||
'strikethrough': 'Strikethrough',
|
'strikethrough': 'Strikethrough',
|
||||||
'createlink': 'Link',
|
'createlink': 'Link',
|
||||||
'insertimage': 'Image'
|
'insertimage': 'Image'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return pens[name];
|
return pens[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.prototype.forEach.call(document.querySelectorAll('form'), function(form) {
|
Array.prototype.forEach.call(document.querySelectorAll('form'), function(form) {
|
||||||
var shouldAllowAlert = false;
|
var shouldAllowAlert = false;
|
||||||
form.addEventListener('submit', function() {
|
form.addEventListener('submit', function() {
|
||||||
if (shouldAllowAlert) {
|
if (shouldAllowAlert) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(editor) {
|
Array.prototype.forEach.call(document.querySelectorAll('.textarea'), function(editor) {
|
||||||
var name = editor.dataset.name;
|
var name = editor.dataset.name;
|
||||||
var textarea = document.querySelector('textarea[name="' + name + '"]');
|
var textarea = document.querySelector('textarea[name="' + name + '"]');
|
||||||
if (!textarea) {
|
if (!textarea) {
|
||||||
textarea = document.createElement('textarea');
|
textarea = document.createElement('textarea');
|
||||||
textarea.name = name;
|
textarea.name = name;
|
||||||
textarea.style.display = 'none';
|
textarea.style.display = 'none';
|
||||||
form.appendChild(textarea);
|
form.appendChild(textarea);
|
||||||
}
|
}
|
||||||
textarea.value = editor.innerHTML;
|
textarea.value = editor.innerHTML;
|
||||||
if (pens[name]) {
|
if (pens[name]) {
|
||||||
pens[name].destroy();
|
pens[name].destroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, false);
|
}, false);
|
||||||
Array.prototype.forEach.call(form.querySelectorAll('button'), function(button) {
|
Array.prototype.forEach.call(form.querySelectorAll('button'), function(button) {
|
||||||
form.addEventListener('click', function(event) {
|
form.addEventListener('click', function(event) {
|
||||||
shouldAllowAlert = (event.target.value === 'cancel');
|
shouldAllowAlert = (event.target.value === 'cancel');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Array.prototype.forEach.call(document.querySelectorAll('.check-box-field .other input'), function(input) {
|
Array.prototype.forEach.call(document.querySelectorAll('.check-box-field .other input'), function(input) {
|
||||||
var checkbox = document.getElementById(input.parentElement.parentElement.attributes.for.value);
|
var checkbox = document.getElementById(input.parentElement.parentElement.attributes.for.value);
|
||||||
input.addEventListener('keyup', function(event) {
|
input.addEventListener('keyup', function(event) {
|
||||||
if (event.target.value) {
|
if (event.target.value) {
|
||||||
checkbox.checked = true;
|
checkbox.checked = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
input.addEventListener('click', function(event) {
|
input.addEventListener('click', function(event) {
|
||||||
checkbox.checked = true;
|
checkbox.checked = true;
|
||||||
});
|
});
|
||||||
var setRequired = function() {
|
var setRequired = function() {
|
||||||
if (checkbox.checked) {
|
if (checkbox.checked) {
|
||||||
input.setAttribute('required', 'required');
|
input.setAttribute('required', 'required');
|
||||||
} else {
|
} else {
|
||||||
input.removeAttribute('required');
|
input.removeAttribute('required');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Array.prototype.forEach.call(document.querySelectorAll('.check-box-field input'), function(_input) {
|
Array.prototype.forEach.call(document.querySelectorAll('.check-box-field input'), function(_input) {
|
||||||
_input.addEventListener('change', function(event) { setRequired(); });
|
_input.addEventListener('change', function(event) { setRequired(); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Array.prototype.forEach.call(document.querySelectorAll('[data-toggles]'), function(checkbox) {
|
Array.prototype.forEach.call(document.querySelectorAll('[data-toggles]'), function(checkbox) {
|
||||||
var toggles = document.getElementById(checkbox.dataset.toggles);
|
var toggles = document.getElementById(checkbox.dataset.toggles);
|
||||||
toggles.classList.add('toggleable');
|
toggles.classList.add('toggleable');
|
||||||
var form = checkbox.parentNode;
|
var form = checkbox.parentNode;
|
||||||
while (form && form.nodeName != 'FORM') {
|
while (form && form.nodeName != 'FORM') {
|
||||||
form = form.parentNode;
|
form = form.parentNode;
|
||||||
}
|
}
|
||||||
var toggle = function() {
|
var toggle = function() {
|
||||||
toggles.classList[checkbox.checked ? 'add' : 'remove']('open');
|
toggles.classList[checkbox.checked ? 'add' : 'remove']('open');
|
||||||
if (form) {
|
if (form) {
|
||||||
if (checkbox.checked) {
|
if (checkbox.checked) {
|
||||||
form.removeAttribute('novalidate');
|
form.removeAttribute('novalidate');
|
||||||
} else {
|
} else {
|
||||||
form.setAttribute('novalidate', 'novalidate');
|
form.setAttribute('novalidate', 'novalidate');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
toggle();
|
toggle();
|
||||||
checkbox.addEventListener('change', function(event) { 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' : '';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
31
app/assets/javascripts/filefield.js
Normal 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);
|
||||||
|
})();
|
4
app/assets/javascripts/jquery.min.js
vendored
@ -230,4 +230,15 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
initNode();
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
117
app/assets/javascripts/map.js
Normal 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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
26
app/assets/javascripts/userfield.js
Normal 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);
|
||||||
|
})();
|
@ -14,156 +14,165 @@ $colour-5: #02CA9E; // green
|
|||||||
|
|
||||||
$white: #FFFEFE;
|
$white: #FFFEFE;
|
||||||
$black: #333;
|
$black: #333;
|
||||||
|
$gray: #E8E8E8;
|
||||||
|
$light-gray: #EEE;
|
||||||
|
$mid-gray: #888;
|
||||||
|
// $red: #B24C63;
|
||||||
|
$red: #FF5A5F;
|
||||||
|
|
||||||
$link-colour: darken($colour-1, 13%);
|
$link-colour: darken($colour-1, 13%);
|
||||||
|
|
||||||
@mixin default-box-shadow($direction: top, $distance: 1, $inset: false, $additional-shadow: false) {
|
@mixin default-box-shadow($direction: top, $distance: 1, $inset: false, $additional-shadow: false) {
|
||||||
@if capable_of(box-shadow) {
|
@if capable_of(box-shadow) {
|
||||||
$offset: 0.2em;
|
$offset: 0.2em;
|
||||||
@if $direction == right or $direction == bottom {
|
@if $direction == right or $direction == bottom {
|
||||||
$offset: -$offset;
|
$offset: -$offset;
|
||||||
}
|
}
|
||||||
@if $direction == left or $direction == right {
|
@if $direction == left or $direction == right {
|
||||||
$offset: '#{$offset} 0';
|
$offset: '#{$offset} 0';
|
||||||
} @else {
|
} @else {
|
||||||
$offset: '0 #{$offset}';
|
$offset: '0 #{$offset}';
|
||||||
}
|
}
|
||||||
@if $inset {
|
@if $inset {
|
||||||
$offset: 'inset #{$offset}';
|
$offset: 'inset #{$offset}';
|
||||||
}
|
}
|
||||||
@if $additional-shadow {
|
@if $additional-shadow {
|
||||||
$additional-shadow: ', #{$additional-shadow}';
|
$additional-shadow: ', #{$additional-shadow}';
|
||||||
} @else {
|
} @else {
|
||||||
$additional-shadow: '';
|
$additional-shadow: '';
|
||||||
}
|
}
|
||||||
@include _(box-shadow, #{$offset} 0.8em #{-0.2em * $distance} #000#{$additional-shadow});
|
@include _(box-shadow, #{$offset} 0.8em #{-0.2em * $distance} #000#{$additional-shadow});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin monospace-font {
|
@mixin monospace-font {
|
||||||
@include font(monospace);
|
@include font(monospace);
|
||||||
@include font(monospace-bold);
|
@include font(monospace-bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin translation-pointer {
|
@mixin translation-pointer {
|
||||||
@include keyframes(bouncy) {
|
@include keyframes(bouncy) {
|
||||||
from { transform: translateY(-0.25em); }
|
from { transform: translateY(-0.25em); }
|
||||||
to { transform: translateY(0.25em); }
|
to { transform: translateY(0.25em); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#lingua-franca-pointer {
|
#lingua-franca-pointer {
|
||||||
$colour: $colour-5;
|
$colour: $colour-5;
|
||||||
width: 0.6667em;
|
width: 0.6667em;
|
||||||
height: 1.25em;
|
height: 1.25em;
|
||||||
background-color: $colour;
|
background-color: $colour;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
margin-left: -0.5em;
|
margin-left: -0.5em;
|
||||||
margin-top: -2em;
|
margin-top: -2em;
|
||||||
@include _(mix-blend-mode, exclusion);
|
@include _(mix-blend-mode, exclusion);
|
||||||
@include default-box-shadow(top, 2);
|
@include default-box-shadow(top, 2);
|
||||||
@include _(animation, bouncy 1s infinite alternate);
|
@include _(animation, bouncy 1s infinite alternate);
|
||||||
|
|
||||||
$twidth: 0.8em;
|
$twidth: 0.8em;
|
||||||
@include after {
|
@include after {
|
||||||
content: '';
|
content: '';
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: $colour transparent transparent;
|
border-color: $colour transparent transparent;
|
||||||
border-width: $twidth $twidth 0;
|
border-width: $twidth $twidth 0;
|
||||||
top: 100%;
|
top: 100%;
|
||||||
left: -.4em;
|
left: -.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.up {
|
&.up {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
|
|
||||||
@include after {
|
@include after {
|
||||||
top: auto;
|
top: auto;
|
||||||
bottom: 100%;
|
bottom: 100%;
|
||||||
border-color: transparent transparent $colour;
|
border-color: transparent transparent $colour;
|
||||||
border-width: 0 $twidth $twidth;
|
border-width: 0 $twidth $twidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin text-stroke {
|
||||||
|
@include _(text-stroke, 1px rgba(0, 0, 0, 0.25));
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin button {
|
@mixin button {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: $white;
|
color: $white;
|
||||||
background-color: $colour-1;
|
background-color: $colour-1;
|
||||||
border: 0;
|
border: 0;
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
font-size: 1.25em;
|
font-size: 1.25em;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
border-bottom: 0.125em solid rgba(0, 0, 0, 0.15);
|
border-bottom: 0.125em solid rgba(0, 0, 0, 0.15);
|
||||||
@include _(border-radius, 0.15em);
|
@include _(border-radius, 0.15em);
|
||||||
@include default-box-shadow(top, 2);
|
@include default-box-shadow(top, 2);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@include _(text-stroke, 1px rgba(0, 0, 0, 0.25));
|
@include text-stroke;
|
||||||
|
|
||||||
@include before {
|
@include before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
background-color: rgba(0,0,0,0);
|
background-color: rgba(0,0,0,0);
|
||||||
@include _(transition, background-color 150ms ease-in-out);
|
@include _(transition, background-color 150ms ease-in-out);
|
||||||
}
|
}
|
||||||
/*@include before-and-after {
|
/*@include before-and-after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: block;
|
display: block;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 100%;
|
right: 100%;
|
||||||
font-size: 1.15em;
|
font-size: 1.15em;
|
||||||
background-color: rgba(0, 0, 0, 0);
|
background-color: rgba(0, 0, 0, 0);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
@include _(transition, all 250ms ease-in-out);
|
@include _(transition, all 250ms ease-in-out);
|
||||||
}
|
}
|
||||||
@include before {
|
@include before {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
}
|
}
|
||||||
@include after {
|
@include after {
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1em 0 1em 1em;
|
border-width: 1em 0 1em 1em;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/*&:hover,
|
/*&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@include before-and-after {
|
@include before-and-after {
|
||||||
right: -1em;
|
right: -1em;
|
||||||
border-left-color: rgba(0, 0, 0, 0.15);
|
border-left-color: rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@include before {
|
@include before {
|
||||||
background-color: rgba(0, 0, 0, 0.15);
|
background-color: rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
@include _(transform, scale(0.95));
|
@include _(transform, scale(0.95));
|
||||||
|
|
||||||
@include after {
|
@include after {
|
||||||
left: 120%;
|
left: 120%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
@include _(opacity, 0.5);
|
@include _(opacity, 0.5);
|
||||||
cursor: inherit;
|
cursor: inherit;
|
||||||
|
|
||||||
@include before-and-after {
|
@include before-and-after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
"chrome": ["51"]
|
"chrome": ["51"]
|
||||||
},
|
},
|
||||||
"development": {
|
"development": {
|
||||||
"and_chr": ["53"],
|
"and_chr": ["54"],
|
||||||
"chrome": ["53"],
|
"chrome": ["54"],
|
||||||
"edge": ["13"],
|
"edge": ["13"],
|
||||||
"firefox": ["44"],
|
"firefox": ["44"],
|
||||||
"ie": ["11"],
|
"ie": ["11"],
|
||||||
|
36
app/controllers/admin_controller.rb
Normal 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
|
1208
app/controllers/conference_administration_controller.rb
Normal file
355
app/controllers/workshops_controller.rb
Normal 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
|
@ -1,180 +1,180 @@
|
|||||||
require 'diffy'
|
require 'diffy'
|
||||||
|
|
||||||
class UserMailer < ActionMailer::Base
|
class UserMailer < ActionMailer::Base
|
||||||
add_template_helper(ApplicationHelper)
|
add_template_helper(ApplicationHelper)
|
||||||
include LinguaFrancaHelper
|
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)
|
def email_confirmation(confirmation)
|
||||||
@confirmation = EmailConfirmation.find(confirmation) if confirmation.present?
|
@confirmation = EmailConfirmation.find(confirmation) if confirmation.present?
|
||||||
I18n.locale = @confirmation.user.locale if @confirmation.user.locale.present?
|
I18n.locale = @confirmation.user.locale if @confirmation.user.locale.present?
|
||||||
@subject = _'email.subject.confirm_email','Please confirm your email address'
|
@subject = _'email.subject.confirm_email','Please confirm your email address'
|
||||||
mail to: @confirmation.user.named_email, subject: @subject
|
mail to: @confirmation.user.named_email, subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_confirmation(registration)
|
def registration_confirmation(registration)
|
||||||
@registration = ConferenceRegistration.find(registration) if registration.present?
|
@registration = ConferenceRegistration.find(registration) if registration.present?
|
||||||
@conference = @registration.conference
|
@conference = @registration.conference
|
||||||
@user = @registration.user
|
@user = @registration.user
|
||||||
I18n.locale = @user.locale if @user.locale.present?
|
I18n.locale = @user.locale if @user.locale.present?
|
||||||
@subject = @conference.registration_status.to_sym == :pre ?
|
@subject = @conference.registration_status.to_sym == :pre ?
|
||||||
_(
|
_(
|
||||||
'email.subject.pre_registration_confirmed',
|
'email.subject.pre_registration_confirmed',
|
||||||
"Thank you for pre-registering for #{@conference.title}",
|
"Thank you for pre-registering for #{@conference.title}",
|
||||||
:vars => {:conference_title => @conference.title}
|
:vars => {:conference_title => @conference.title}
|
||||||
) : _(
|
) : _(
|
||||||
'email.subject.registration_confirmed',
|
'email.subject.registration_confirmed',
|
||||||
"Thank you for registering for #{@conference.title}",
|
"Thank you for registering for #{@conference.title}",
|
||||||
:vars => {:conference_title => @conference.title}
|
:vars => {:conference_title => @conference.title}
|
||||||
)
|
)
|
||||||
mail to: @user.named_email, subject: @subject
|
mail to: @user.named_email, subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def broadcast(host, subject, content, user, conference)
|
def broadcast(host, subject, content, user, conference)
|
||||||
@host = host
|
@host = host
|
||||||
@content = content
|
@content = content
|
||||||
@banner = nil
|
@banner = nil
|
||||||
@conference = Conference.find(conference) if conference.present?
|
@conference = Conference.find(conference) if conference.present?
|
||||||
@user = User.find(user) if user.present?
|
@user = User.find(user) if user.present?
|
||||||
@subject = "[#{@conference ? @conference.title : 'Bike!Bike!'}] #{subject}"
|
@subject = "[#{@conference ? @conference.title : 'Bike!Bike!'}] #{subject}"
|
||||||
if @user && @user.named_email
|
if @user && @user.named_email
|
||||||
mail to: @user.named_email, subject: @subject
|
mail to: @user.named_email, subject: @subject
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def workshop_facilitator_request(workshop, requester, message)
|
def workshop_facilitator_request(workshop, requester, message)
|
||||||
@workshop = Workshop.find(workshop) if workshop.present?
|
@workshop = Workshop.find(workshop) if workshop.present?
|
||||||
@requester = User.find(requester) if requester.present?
|
@requester = User.find(requester) if requester.present?
|
||||||
addresses = []
|
addresses = []
|
||||||
I18n.locale = @workshop.active_facilitators.first.locale if @workshop.active_facilitators.first.locale.present?
|
I18n.locale = @workshop.active_facilitators.first.locale if @workshop.active_facilitators.first.locale.present?
|
||||||
@workshop.active_facilitators.each do |f|
|
@workshop.active_facilitators.each do |f|
|
||||||
addresses << f.named_email
|
addresses << f.named_email
|
||||||
end
|
end
|
||||||
@message = message
|
@message = message
|
||||||
@conference = Conference.find(@workshop.conference_id)
|
@conference = Conference.find(@workshop.conference_id)
|
||||||
@subject = _('email.subject.workshop_facilitator_request',
|
@subject = _('email.subject.workshop_facilitator_request',
|
||||||
"Request to facilitate #{@workshop.title} from #{@requester.name}",
|
"Request to facilitate #{@workshop.title} from #{@requester.name}",
|
||||||
:vars => {:workshop_title => @workshop.title, :requester_name => @requester.firstname})
|
:vars => {:workshop_title => @workshop.title, :requester_name => @requester.firstname})
|
||||||
mail to: addresses, reply_to: addresses + [@requester.named_email], subject: @subject
|
mail to: addresses, reply_to: addresses + [@requester.named_email], subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def workshop_facilitator_request_approved(workshop, user)
|
def workshop_facilitator_request_approved(workshop, user)
|
||||||
@workshop = Workshop.find(workshop) if workshop.present?
|
@workshop = Workshop.find(workshop) if workshop.present?
|
||||||
@conference = Conference.find(@workshop.conference_id)
|
@conference = Conference.find(@workshop.conference_id)
|
||||||
@user = User.find(user) if user.present?
|
@user = User.find(user) if user.present?
|
||||||
I18n.locale = @user.locale if @user.locale.present?
|
I18n.locale = @user.locale if @user.locale.present?
|
||||||
@subject = (_'email.subject.workshop_request_approved',
|
@subject = (_'email.subject.workshop_request_approved',
|
||||||
"You have been added as a facilitator of #{@workshop.title}",
|
"You have been added as a facilitator of #{@workshop.title}",
|
||||||
:vars => {:workshop_title => @workshop.title})
|
:vars => {:workshop_title => @workshop.title})
|
||||||
mail to: @user.named_email, subject: @subject
|
mail to: @user.named_email, subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def workshop_facilitator_request_denied(workshop, user)
|
def workshop_facilitator_request_denied(workshop, user)
|
||||||
@workshop = Workshop.find(workshop) if workshop.present?
|
@workshop = Workshop.find(workshop) if workshop.present?
|
||||||
@conference = @workshop.conference
|
@conference = @workshop.conference
|
||||||
@user = User.find(user) if user.present?
|
@user = User.find(user) if user.present?
|
||||||
I18n.locale = @user.locale if @user.present? && @user.locale.present?
|
I18n.locale = @user.locale if @user.present? && @user.locale.present?
|
||||||
@subject = (_'email.subject.workshop_request_denied',
|
@subject = (_'email.subject.workshop_request_denied',
|
||||||
"Your request to facilitate #{@workshop.title} has been denied",
|
"Your request to facilitate #{@workshop.title} has been denied",
|
||||||
:vars => {:workshop_title => @workshop.title})
|
:vars => {:workshop_title => @workshop.title})
|
||||||
mail to: @user.named_email, subject: @subject
|
mail to: @user.named_email, subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def workshop_translated(workshop, data, locale, user, translator)
|
def workshop_translated(workshop, data, locale, user, translator)
|
||||||
@workshop = Workshop.find(workshop) if workshop.present?
|
@workshop = Workshop.find(workshop) if workshop.present?
|
||||||
@data = data
|
@data = data
|
||||||
@locale = locale
|
@locale = locale
|
||||||
@locale_name = language_name(locale)
|
@locale_name = language_name(locale)
|
||||||
@user = User.find(user) if user.present?
|
@user = User.find(user) if user.present?
|
||||||
I18n.locale = @user.locale if @user.present? && @user.locale.present?
|
I18n.locale = @user.locale if @user.present? && @user.locale.present?
|
||||||
@translator = User.find(translator) if translator.present?
|
@translator = User.find(translator) if translator.present?
|
||||||
@subject = (_'email.subject.workshop_translated',
|
@subject = (_'email.subject.workshop_translated',
|
||||||
"The #{@locale_name} translation for #{@workshop.title} has been modified",
|
"The #{@locale_name} translation for #{@workshop.title} has been modified",
|
||||||
vars: {language: @language_name, workshop_title: @workshop.title})
|
vars: {language: @language_name, workshop_title: @workshop.title})
|
||||||
|
|
||||||
@wrapper_id = :full_width
|
@wrapper_id = :full_width
|
||||||
|
|
||||||
mail to: @user.named_email, subject: @subject
|
mail to: @user.named_email, subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def workshop_original_content_changed(workshop, data, user, translator)
|
def workshop_original_content_changed(workshop, data, user, translator)
|
||||||
@workshop = Workshop.find(workshop) if workshop.present?
|
@workshop = Workshop.find(workshop) if workshop.present?
|
||||||
@data = data
|
@data = data
|
||||||
@user = User.find(user) if user.present?
|
@user = User.find(user) if user.present?
|
||||||
I18n.locale = @user.locale if @user.present? && @user.locale.present?
|
I18n.locale = @user.locale if @user.present? && @user.locale.present?
|
||||||
@translator = User.find(translator) if translator.present?
|
@translator = User.find(translator) if translator.present?
|
||||||
@subject = (_'email.subject.workshop_original_content_changed',
|
@subject = (_'email.subject.workshop_original_content_changed',
|
||||||
"Original content for #{@workshop.title} has been modified",
|
"Original content for #{@workshop.title} has been modified",
|
||||||
vars: {workshop_title: @workshop.title})
|
vars: {workshop_title: @workshop.title})
|
||||||
@data.each do |field, values|
|
@data.each do |field, values|
|
||||||
diff = Diffy::Diff.new(values[:old], values[:new])
|
diff = Diffy::Diff.new(values[:old], values[:new])
|
||||||
@data[field][:diff] = {
|
@data[field][:diff] = {
|
||||||
text: diff.to_s(:text),
|
text: diff.to_s(:text),
|
||||||
html: diff.to_s(:html)
|
html: diff.to_s(:html)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@wrapper_id = :full_width
|
@wrapper_id = :full_width
|
||||||
|
|
||||||
mail to: @user.named_email, subject: @subject
|
mail to: @user.named_email, subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def workshop_comment(workshop, comment, user)
|
def workshop_comment(workshop, comment, user)
|
||||||
@workshop = Workshop.find(workshop) if workshop.present?
|
@workshop = Workshop.find(workshop) if workshop.present?
|
||||||
@comment = Comment.find(comment) if comment.present?
|
@comment = Comment.find(comment) if comment.present?
|
||||||
@user = User.find(user) if user.present?
|
@user = User.find(user) if user.present?
|
||||||
I18n.locale = @user.locale if @user.present? && @user.locale.present?
|
I18n.locale = @user.locale if @user.present? && @user.locale.present?
|
||||||
|
|
||||||
if @comment.reply?
|
if @comment.reply?
|
||||||
@subject = (_'email.subject.workshop_comment.reply', vars: { user_name: @comment.user.name })
|
@subject = (_'email.subject.workshop_comment.reply', vars: { user_name: @comment.user.name })
|
||||||
else
|
else
|
||||||
@subject = (_'email.subject.workshop_comment.comment', vars: { user_name: @comment.user.name, workshop_title: @workshop.title })
|
@subject = (_'email.subject.workshop_comment.comment', vars: { user_name: @comment.user.name, workshop_title: @workshop.title })
|
||||||
end
|
end
|
||||||
|
|
||||||
mail to: @user.named_email, subject: @subject
|
mail to: @user.named_email, subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_report(subject, message, report, exception, request, params, user, time = nil)
|
def error_report(subject, message, report, exception, request, params, user, time = nil)
|
||||||
@subject = subject
|
@subject = subject
|
||||||
@message = message
|
@message = message
|
||||||
@report = report
|
@report = report
|
||||||
@exception = exception
|
@exception = exception
|
||||||
@request = request
|
@request = request
|
||||||
@params = params
|
@params = params
|
||||||
@time = time
|
@time = time
|
||||||
@user = User.find(user) if user.present?
|
@user = User.find(user) if user.present?
|
||||||
mail to: 'goodgodwin@hotmail.com', subject: @subject
|
mail to: 'goodgodwin@hotmail.com', subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact(from, subject, message, email_list)
|
def contact(from, subject, message, email_list)
|
||||||
@message = message
|
@message = message
|
||||||
@subject = subject
|
@subject = subject
|
||||||
@from = from.is_a?(Integer) ? User.find(from) : from
|
@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
|
mail to: email_list.join(', '), subject: @subject, reply_to: @from.is_a?(User) ? @from.named_email : @from
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_details(from, subject, message, request, params)
|
def contact_details(from, subject, message, request, params)
|
||||||
@message = message
|
@message = message
|
||||||
@subject = "Details for: \"#{subject}\""
|
@subject = "Details for: \"#{subject}\""
|
||||||
@from = from.is_a?(Integer) ? User.find(from) : from
|
@from = from.is_a?(Integer) ? User.find(from) : from
|
||||||
@request = request
|
@request = request
|
||||||
@params = params
|
@params = params
|
||||||
|
|
||||||
mail to: 'goodgodwin@hotmail.com', subject: @subject
|
mail to: 'goodgodwin@hotmail.com', subject: @subject
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def set_host(*args)
|
def set_host(*args)
|
||||||
if Rails.env.production?
|
if Rails.env.production?
|
||||||
@host = "https://#{I18n.locale.to_s}.bikebike.org"
|
@host = "https://#{I18n.locale.to_s}.bikebike.org"
|
||||||
elsif Rails.env.preview?
|
elsif Rails.env.preview?
|
||||||
@host = "https://preview-#{I18n.locale.to_s}.bikebike.org"
|
@host = "https://preview-#{I18n.locale.to_s}.bikebike.org"
|
||||||
else
|
else
|
||||||
@host = UserMailer.default_url_options[:host]
|
@host = UserMailer.default_url_options[:host]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
77
app/models/city.rb
Normal 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
@ -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
|
@ -1,27 +1,27 @@
|
|||||||
class Comment < ActiveRecord::Base
|
class Comment < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
||||||
def comment_object
|
def comment_object
|
||||||
model_type.classify.constantize.find(model_id)
|
model_type.classify.constantize.find(model_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_model(model)
|
def set_model(model)
|
||||||
model_type = model.class.name.tableize
|
model_type = model.class.name.tableize
|
||||||
model_id = model.id
|
model_id = model.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.for(model)
|
def self.for(model)
|
||||||
where(model_type: model.class.name.tableize, model_id: model.id).order(created_at: :asc)
|
where(model_type: model.class.name.tableize, model_id: model.id).order(created_at: :asc)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.create_for(model, user, comment)
|
def self.create_for(model, user, comment)
|
||||||
create(
|
create(
|
||||||
model_type: model.class.name.tableize,
|
model_type: model.class.name.tableize,
|
||||||
model_id: model.id,
|
model_id: model.id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
comment: comment
|
comment: comment
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_comment(user, comment)
|
def add_comment(user, comment)
|
||||||
Comment.create_for(self, user, comment)
|
Comment.create_for(self, user, comment)
|
||||||
@ -32,6 +32,6 @@ class Comment < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def reply?
|
def reply?
|
||||||
model_type == 'comments'
|
model_type == 'comments'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,71 +1,136 @@
|
|||||||
class Conference < ActiveRecord::Base
|
class Conference < ActiveRecord::Base
|
||||||
translates :info, :title, :payment_message
|
translates :info, :title, :payment_message
|
||||||
|
|
||||||
mount_uploader :cover, CoverUploader
|
mount_uploader :cover, CoverUploader
|
||||||
mount_uploader :poster, PosterUploader
|
mount_uploader :poster, PosterUploader
|
||||||
|
|
||||||
belongs_to :conference_type
|
belongs_to :conference_type
|
||||||
|
belongs_to :city
|
||||||
|
|
||||||
has_many :conference_host_organizations, :dependent => :destroy
|
has_many :conference_host_organizations, dependent: :destroy
|
||||||
has_many :organizations, :through => :conference_host_organizations
|
has_many :organizations, through: :conference_host_organizations
|
||||||
has_many :event_locations
|
has_many :conference_administrators, dependent: :destroy
|
||||||
|
has_many :administrators, through: :conference_administrators, source: :user
|
||||||
#has_many :conference_registration_form_fields, :order => 'position ASC', :dependent => :destroy#, :class_name => '::ConferenceRegistrationFormField'
|
has_many :event_locations
|
||||||
#has_many :registration_form_fields, :through => :conference_registration_form_fields
|
|
||||||
|
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
|
def to_param
|
||||||
slug
|
slug
|
||||||
end
|
end
|
||||||
|
|
||||||
def host?(user)
|
def host_organization?(org)
|
||||||
return false unless user.present?
|
return false unless org.present?
|
||||||
organizations.each do |o|
|
org_id = org.is_a?(Organization) ? org.id : org
|
||||||
return true if o.host?(user)
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
def url(action = :show)
|
organizations.each do |o|
|
||||||
path(action)
|
return true if o.id = org_id
|
||||||
end
|
end
|
||||||
|
|
||||||
def path(action = :show)
|
return false
|
||||||
action = action.to_sym
|
end
|
||||||
'/conferences/' + conference_type.slug + '/' + slug + (action == :show ? '' : '/' + action.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def location
|
def host?(user)
|
||||||
organizations.first.location
|
if user.present?
|
||||||
end
|
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)
|
def url(action = :show)
|
||||||
registration = ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id)
|
path(action)
|
||||||
return registration ? registration.is_attending : false
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def registration_exists?(user)
|
def path(action = :show)
|
||||||
ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id).present?
|
action = action.to_sym
|
||||||
end
|
'/conferences/' + conference_type.slug + '/' + slug + (action == :show ? '' : '/' + action.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
def registration_open
|
def location
|
||||||
registration_status == :open
|
return nil unless organizations.present?
|
||||||
end
|
organizations.first.location
|
||||||
|
end
|
||||||
|
|
||||||
def registration_status
|
def registered?(user)
|
||||||
s = read_attribute(:registration_status)
|
registration = ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id)
|
||||||
s.present? ? s.to_sym : nil
|
return registration ? registration.is_attending : false
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_status=(new_registration_status)
|
def registration_exists?(user)
|
||||||
write_attribute :registration_status, new_registration_status.to_s
|
ConferenceRegistration.find_by(:user_id => user.id, :conference_id => id).present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.default_payment_amounts
|
def registration_open
|
||||||
[25, 50, 100]
|
registration_status == :open
|
||||||
end
|
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
|
end
|
||||||
|
4
app/models/conference_administrator.rb
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
class ConferenceAdministrator < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :conference
|
||||||
|
end
|
@ -1,58 +1,58 @@
|
|||||||
class ConferenceRegistration < ActiveRecord::Base
|
class ConferenceRegistration < ActiveRecord::Base
|
||||||
belongs_to :conference
|
belongs_to :conference
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
has_many :conference_registration_responses
|
has_many :conference_registration_responses
|
||||||
|
|
||||||
AttendingOptions = [:yes, :no]
|
AttendingOptions = [:yes, :no]
|
||||||
|
|
||||||
def languages
|
def languages
|
||||||
user.languages
|
user.languages
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.all_housing_options
|
def self.all_housing_options
|
||||||
[:none, :tent, :house]
|
[:none, :tent, :house]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.all_spaces
|
def self.all_spaces
|
||||||
[:bed_space, :floor_space, :tent_space]
|
[:bed_space, :floor_space, :tent_space]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.all_bike_options
|
def self.all_bike_options
|
||||||
[:yes, :no]
|
[:yes, :no]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.all_food_options
|
def self.all_food_options
|
||||||
[:meat, :vegetarian, :vegan]
|
[:meat, :vegetarian, :vegan]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.all_considerations
|
def self.all_considerations
|
||||||
[:vegan, :smoking, :pets, :quiet]
|
[:vegan, :smoking, :pets, :quiet]
|
||||||
end
|
end
|
||||||
|
|
||||||
def status(was = false)
|
def status(was = false)
|
||||||
return :unregistered if user.firstname.blank? || self.send(was ? :city_was : :city).blank?
|
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 :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
|
return :preregistered
|
||||||
end
|
end
|
||||||
|
|
||||||
around_update :check_status
|
around_update :check_status
|
||||||
|
|
||||||
def check_status
|
def check_status
|
||||||
yield
|
yield
|
||||||
|
|
||||||
old_status = status(true)
|
old_status = status(true)
|
||||||
new_status = status
|
new_status = status
|
||||||
|
|
||||||
if old_status.present? && old_status != new_status
|
if old_status.present? && old_status != new_status
|
||||||
if (conference.registration_status == :pre && new_status == :preregistered) ||
|
if (conference.registration_status == :pre && new_status == :preregistered) ||
|
||||||
(conference.registration_status == :open && new_status == :registered)
|
(conference.registration_status == :open && new_status == :registered)
|
||||||
|
|
||||||
UserMailer.send_mail :registration_confirmation do
|
UserMailer.send_mail :registration_confirmation do
|
||||||
{
|
{
|
||||||
:args => self
|
:args => self
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
class Event < ActiveRecord::Base
|
class Event < ActiveRecord::Base
|
||||||
translates :info, :title
|
translates :info, :title
|
||||||
|
|
||||||
belongs_to :conference
|
belongs_to :conference
|
||||||
belongs_to :event_location
|
belongs_to :event_location
|
||||||
|
|
||||||
def conference_day
|
def conference_day
|
||||||
return nil unless start_time.present? && end_time.present?
|
return nil unless start_time.present? && end_time.present?
|
||||||
|
|
||||||
start_day = conference.start_date.change(hour: 0, minute: 0, second: 0)
|
start_day = conference.start_date.change(hour: 0, minute: 0, second: 0)
|
||||||
w_start_day = start_time.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
|
return (((w_start_day - start_day) / 86400) + 1).to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
def duration
|
def duration
|
||||||
return nil unless start_time.present? && end_time.present?
|
return nil unless start_time.present? && end_time.present?
|
||||||
((end_time - start_time) / 60).to_i
|
((end_time - start_time) / 60).to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
class LocationsOrganization < ActiveRecord::Base
|
class LocationsOrganization < ActiveRecord::Base
|
||||||
belongs_to :location
|
belongs_to :location
|
||||||
belongs_to :organization
|
belongs_to :organization
|
||||||
|
|
||||||
self.primary_key = :location_id
|
self.primary_key = :location_id
|
||||||
end
|
end
|
||||||
|
@ -1,71 +1,77 @@
|
|||||||
class Organization < ActiveRecord::Base
|
class Organization < ActiveRecord::Base
|
||||||
mount_uploader :logo, LogoUploader
|
mount_uploader :logo, LogoUploader
|
||||||
mount_uploader :avatar, AvatarUploader
|
mount_uploader :avatar, AvatarUploader
|
||||||
mount_uploader :cover, CoverUploader
|
mount_uploader :cover, CoverUploader
|
||||||
|
|
||||||
has_many :locations_organization
|
has_many :locations_organization
|
||||||
has_many :locations, :through => :locations_organization
|
has_many :locations, through: :locations_organization
|
||||||
|
|
||||||
has_many :user_organization_relationships, :dependent => :destroy
|
has_many :user_organization_relationships, dependent: :destroy
|
||||||
has_many :users, :through => :user_organization_relationships
|
has_many :users, through: :user_organization_relationships
|
||||||
|
|
||||||
accepts_nested_attributes_for :locations, :reject_if => proc {|l| l[id].blank?}
|
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
|
accepts_nested_attributes_for :user_organization_relationships, :reject_if => proc {|u| u[:user_id].blank?}, :allow_destroy => true
|
||||||
before_create :make_slug
|
before_create :make_slug
|
||||||
|
|
||||||
def location
|
def location
|
||||||
locations.first
|
locations.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def longitude
|
def longitude
|
||||||
location.longitude
|
location.longitude
|
||||||
end
|
end
|
||||||
|
|
||||||
def latitude
|
def latitude
|
||||||
location.latitude
|
location.latitude
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
slug
|
slug
|
||||||
end
|
end
|
||||||
|
|
||||||
def host?(user)
|
def host?(user)
|
||||||
return false unless user.present?
|
return false unless user.present?
|
||||||
return true if user.administrator?
|
return true if user.administrator?
|
||||||
|
|
||||||
users.each do |u|
|
users.each do |u|
|
||||||
return true if u.id == user.id
|
return true if u.id == user.id
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_slug(name, location = nil)
|
def generate_slug(name, location = nil)
|
||||||
s = name.gsub(/[^a-z1-9]+/i, '-').chomp('-').gsub(/\-([A-Z])/, '\1')
|
s = name.gsub(/[^a-z1-9]+/i, '-').chomp('-').gsub(/\-([A-Z])/, '\1')
|
||||||
if Organization.find_by(:slug => s).present? && !location.nil?
|
if Organization.find_by(:slug => s).present? && !location.nil?
|
||||||
if location.city.present?
|
if location.city.present?
|
||||||
s += '-' + location.city
|
s += '-' + location.city
|
||||||
end
|
end
|
||||||
if Organization.find_by(:slug => s).present? && location.territory.present?
|
if Organization.find_by(:slug => s).present? && location.territory.present?
|
||||||
s += '-' + location.territory
|
s += '-' + location.territory
|
||||||
end
|
end
|
||||||
if Organization.find_by(:slug => s).present?
|
if Organization.find_by(:slug => s).present?
|
||||||
s += '-' + location.country
|
s += '-' + location.country
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
attempt = 1
|
attempt = 1
|
||||||
ss = s
|
ss = s
|
||||||
|
|
||||||
while Organization.find_by(:slug => s)
|
while Organization.find_by(:slug => s)
|
||||||
attempt += 1
|
attempt += 1
|
||||||
s = ss + '-' + attempt.to_s
|
s = ss + '-' + attempt.to_s
|
||||||
end
|
end
|
||||||
s
|
s
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def self.find_by_city(city)
|
||||||
def make_slug
|
Organization.joins(:locations).where(locations: {
|
||||||
if !self.slug
|
city_id: city.is_a?(City) ? city.id : city
|
||||||
self.slug = generate_slug(self.name, self.locations && self.locations[0])
|
})
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
private
|
||||||
|
def make_slug
|
||||||
|
if !self.slug
|
||||||
|
self.slug = generate_slug(self.name, self.locations && self.locations[0])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,62 +1,67 @@
|
|||||||
class User < ActiveRecord::Base
|
class User < ActiveRecord::Base
|
||||||
authenticates_with_sorcery! do |config|
|
authenticates_with_sorcery! do |config|
|
||||||
config.authentications_class = Authentication
|
config.authentications_class = Authentication
|
||||||
end
|
end
|
||||||
|
|
||||||
validates :email, uniqueness: true
|
validates :email, uniqueness: true
|
||||||
|
|
||||||
mount_uploader :avatar, AvatarUploader
|
mount_uploader :avatar, AvatarUploader
|
||||||
|
|
||||||
has_many :user_organization_relationships
|
has_many :user_organization_relationships
|
||||||
has_many :organizations, through: :user_organization_relationships
|
has_many :organizations, through: :user_organization_relationships
|
||||||
has_many :authentications, :dependent => :destroy
|
has_many :conferences, through: :conference_administrators
|
||||||
accepts_nested_attributes_for :authentications
|
has_many :authentications, :dependent => :destroy
|
||||||
|
accepts_nested_attributes_for :authentications
|
||||||
|
|
||||||
before_update do |user|
|
before_update do |user|
|
||||||
user.locale ||= I18n.locale
|
user.locale ||= I18n.locale
|
||||||
end
|
end
|
||||||
|
|
||||||
before_save do |user|
|
before_save do |user|
|
||||||
user.locale ||= I18n.locale
|
user.locale ||= I18n.locale
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_translate?(to_locale = nil, from_locale = nil)
|
def can_translate?(to_locale = nil, from_locale = nil)
|
||||||
is_translator unless to_locale.present?
|
is_translator unless to_locale.present?
|
||||||
|
|
||||||
from_locale = I18n.locale unless from_locale.present?
|
from_locale = I18n.locale unless from_locale.present?
|
||||||
return languages.present? &&
|
return languages.present? &&
|
||||||
to_locale.to_s != from_locale.to_s &&
|
to_locale.to_s != from_locale.to_s &&
|
||||||
languages.include?(to_locale.to_s) &&
|
languages.include?(to_locale.to_s) &&
|
||||||
languages.include?(from_locale.to_s)
|
languages.include?(from_locale.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
firstname || username || email
|
firstname || username || email
|
||||||
end
|
end
|
||||||
|
|
||||||
def named_email
|
def named_email
|
||||||
name = firstname || username
|
name = firstname || username
|
||||||
return email unless name
|
return email unless name
|
||||||
return "#{name} <#{email}>"
|
return "#{name} <#{email}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def administrator?
|
def administrator?
|
||||||
role == 'administrator'
|
role == 'administrator'
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.AVAILABLE_LANGUAGES
|
def self.AVAILABLE_LANGUAGES
|
||||||
[:en, :es, :fr, :ar]
|
[:en, :es, :fr, :ar]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.get(email)
|
def self.get(email)
|
||||||
user = where(email: email).first
|
user = where(email: email).first
|
||||||
|
|
||||||
unless user
|
unless user
|
||||||
user = new(email: email)
|
user = new(email: email)
|
||||||
user.save!
|
user.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
return user
|
return user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.find_user(email)
|
||||||
|
User.where('lower(email) = ?', email.downcase).first
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
class UserOrganizationRelationship < ActiveRecord::Base
|
class UserOrganizationRelationship < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :organization
|
belongs_to :organization
|
||||||
|
|
||||||
Administrator = 'administrator'
|
Administrator = 'administrator'
|
||||||
Member = 'member'
|
Member = 'member'
|
||||||
|
|
||||||
DefaultRelationship = Member
|
DefaultRelationship = Member
|
||||||
|
|
||||||
AllRelationships = [Administrator, Member]
|
AllRelationships = [Administrator, Member]
|
||||||
end
|
end
|
||||||
|
@ -3,102 +3,102 @@ require 'carrierwave/processing/mini_magick'
|
|||||||
|
|
||||||
class AvatarUploader < CarrierWave::Uploader::Base
|
class AvatarUploader < CarrierWave::Uploader::Base
|
||||||
|
|
||||||
include CarrierWave::ImageOptimizer
|
include CarrierWave::ImageOptimizer
|
||||||
include CarrierWave::MiniMagick
|
include CarrierWave::MiniMagick
|
||||||
|
|
||||||
# Include RMagick or MiniMagick support:
|
# Include RMagick or MiniMagick support:
|
||||||
# include CarrierWave::RMagick
|
# include CarrierWave::RMagick
|
||||||
# include CarrierWave::MiniMagick
|
# 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
|
storage :file
|
||||||
process :optimize
|
process :optimize
|
||||||
|
|
||||||
@@sizes = {:thumb => [120, 120], :icon => [48, 48], :preview => [360, 120], :normal => [512, 512]}
|
@@sizes = {:thumb => [120, 120], :icon => [48, 48], :preview => [360, 120], :normal => [512, 512]}
|
||||||
# storage :fog
|
# storage :fog
|
||||||
|
|
||||||
# Override the directory where uploaded files will be stored.
|
# Override the directory where uploaded files will be stored.
|
||||||
# This is a sensible default for uploaders that are meant to be mounted:
|
# This is a sensible default for uploaders that are meant to be mounted:
|
||||||
def store_dir
|
def store_dir
|
||||||
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Provide a default URL as a default if there hasn't been a file uploaded:
|
# Provide a default URL as a default if there hasn't been a file uploaded:
|
||||||
def default_url
|
# def default_url
|
||||||
# # For Rails 3.1+ asset pipeline compatibility:
|
# # For Rails 3.1+ asset pipeline compatibility:
|
||||||
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
|
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
|
||||||
#
|
#
|
||||||
#"/images/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')
|
# "http://placehold.it/" + (@@sizes[version_name] || [300, 300]).join('x')
|
||||||
end
|
#end
|
||||||
|
|
||||||
# Process files as they are uploaded:
|
# Process files as they are uploaded:
|
||||||
# process :scale => [200, 300]
|
# process :scale => [200, 300]
|
||||||
#
|
#
|
||||||
#def scale(width, height)
|
#def scale(width, height)
|
||||||
#end
|
#end
|
||||||
|
|
||||||
# Create different versions of your uploaded files:
|
# Create different versions of your uploaded files:
|
||||||
version :thumb do
|
version :thumb do
|
||||||
process :resize_to_fill => @@sizes[:thumb]
|
process :resize_to_fill => @@sizes[:thumb]
|
||||||
end
|
end
|
||||||
|
|
||||||
version :icon do
|
version :icon do
|
||||||
process :resize_to_fill => @@sizes[:icon]
|
process :resize_to_fill => @@sizes[:icon]
|
||||||
end
|
end
|
||||||
|
|
||||||
version :preview do
|
version :preview do
|
||||||
process :resize_to_fit => @@sizes[:preview]
|
process :resize_to_fit => @@sizes[:preview]
|
||||||
end
|
end
|
||||||
|
|
||||||
version :normal do
|
version :normal do
|
||||||
process :resize_to_fit => @@sizes[:normal]
|
process :resize_to_fit => @@sizes[:normal]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add a white list of extensions which are allowed to be uploaded.
|
# Add a white list of extensions which are allowed to be uploaded.
|
||||||
# For images you might use something like this:
|
# For images you might use something like this:
|
||||||
# def extension_white_list
|
# def extension_white_list
|
||||||
# %w(jpg jpeg gif png)
|
# %w(jpg jpeg gif png)
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# Override the filename of the uploaded files:
|
# Override the filename of the uploaded files:
|
||||||
# Avoid using model.id or version_name here, see uploader/store.rb for details.
|
# Avoid using model.id or version_name here, see uploader/store.rb for details.
|
||||||
# def filename
|
# def filename
|
||||||
# "something.jpg" if original_filename
|
# "something.jpg" if original_filename
|
||||||
# end
|
# end
|
||||||
|
|
||||||
def image
|
def image
|
||||||
@image ||= MiniMagick::Image.open(file.path)
|
@image ||= MiniMagick::Image.open(file.path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_landscape?
|
def is_landscape?
|
||||||
image['width'] > (image['height'] * 1.25)
|
image['width'] > (image['height'] * 1.25)
|
||||||
end
|
end
|
||||||
|
|
||||||
#def recreate_versions!(*versions)
|
#def recreate_versions!(*versions)
|
||||||
# if !current_path.nil?
|
# if !current_path.nil?
|
||||||
# current_path = "'" + (current_path || '') + "'"
|
# current_path = "'" + (current_path || '') + "'"
|
||||||
# end
|
# end
|
||||||
# super(*versions)
|
# super(*versions)
|
||||||
#end
|
#end
|
||||||
|
|
||||||
# def manipulate!
|
# def manipulate!
|
||||||
# cache_stored_file! if !cached?
|
# cache_stored_file! if !cached?
|
||||||
# image = ::MiniMagick::Image.open(current_path)
|
# image = ::MiniMagick::Image.open(current_path)
|
||||||
#
|
#
|
||||||
# begin
|
# begin
|
||||||
# image.format(@format.to_s.downcase) if @format
|
# image.format(@format.to_s.downcase) if @format
|
||||||
# image = yield(image)
|
# image = yield(image)
|
||||||
# image.write(current_path)
|
# image.write(current_path)
|
||||||
# image.run_command("identify", '"' + current_path + '"')
|
# image.run_command("identify", '"' + current_path + '"')
|
||||||
# ensure
|
# ensure
|
||||||
# image.destroy!
|
# image.destroy!
|
||||||
# end
|
# end
|
||||||
# rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
|
# rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
|
||||||
# default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en)
|
# 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)
|
# message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default)
|
||||||
# raise CarrierWave::ProcessingError, message
|
# raise CarrierWave::ProcessingError, message
|
||||||
# end
|
# end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -3,67 +3,67 @@ require 'carrierwave/processing/mini_magick'
|
|||||||
|
|
||||||
class PosterUploader < CarrierWave::Uploader::Base
|
class PosterUploader < CarrierWave::Uploader::Base
|
||||||
|
|
||||||
include CarrierWave::ImageOptimizer
|
include CarrierWave::ImageOptimizer
|
||||||
include CarrierWave::MiniMagick
|
include CarrierWave::MiniMagick
|
||||||
|
|
||||||
storage :file
|
storage :file
|
||||||
process :optimize
|
process :optimize
|
||||||
|
|
||||||
@@sizes = {
|
@@sizes = {
|
||||||
:thumb => [120, 120],
|
:thumb => [120, 120],
|
||||||
:icon => [48, 48],
|
:icon => [48, 48],
|
||||||
:preview => [512, 512],
|
:preview => [512, 512],
|
||||||
:full => [1024, 1024]
|
:full => [1024, 1024]
|
||||||
}
|
}
|
||||||
|
|
||||||
def store_dir
|
def store_dir
|
||||||
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
version :thumb do
|
version :thumb do
|
||||||
process :resize_to_fill => @@sizes[:thumb]
|
process :resize_to_fill => @@sizes[:thumb]
|
||||||
end
|
end
|
||||||
|
|
||||||
version :icon do
|
version :icon do
|
||||||
process :resize_to_fill => @@sizes[:icon]
|
process :resize_to_fill => @@sizes[:icon]
|
||||||
end
|
end
|
||||||
|
|
||||||
version :preview do
|
version :preview do
|
||||||
process :resize_to_fit => @@sizes[:preview]
|
process :resize_to_fit => @@sizes[:preview]
|
||||||
end
|
end
|
||||||
|
|
||||||
version :full do
|
version :full do
|
||||||
process :resize_to_fit => @@sizes[:full]
|
process :resize_to_fit => @@sizes[:full]
|
||||||
end
|
end
|
||||||
|
|
||||||
def image
|
def image
|
||||||
@image ||= MiniMagick::Image.open(file.path)
|
@image ||= MiniMagick::Image.open(file.path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_landscape?
|
def is_landscape?
|
||||||
image['width'] > image['height']
|
image['width'] > image['height']
|
||||||
end
|
end
|
||||||
|
|
||||||
def manipulate!
|
def manipulate!
|
||||||
cache_stored_file! if !cached?
|
cache_stored_file! if !cached?
|
||||||
image = ::MiniMagick::Image.open(current_path)
|
image = ::MiniMagick::Image.open(current_path)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
image.format(@format.to_s.downcase) if @format
|
image.format(@format.to_s.downcase) if @format
|
||||||
image = yield(image)
|
image = yield(image)
|
||||||
image.write(current_path)
|
image.write(current_path)
|
||||||
begin
|
begin
|
||||||
image.run_command("identify", current_path)
|
image.run_command("identify", current_path)
|
||||||
rescue
|
rescue
|
||||||
image.run_command("identify", '"' + current_path + '"')
|
image.run_command("identify", '"' + current_path + '"')
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
image.destroy!
|
image.destroy!
|
||||||
end
|
end
|
||||||
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
|
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
|
||||||
default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en)
|
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)
|
message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default)
|
||||||
raise CarrierWave::ProcessingError, message
|
raise CarrierWave::ProcessingError, message
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
24
app/views/admin/new.html.haml
Normal 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'
|
@ -1,20 +1,20 @@
|
|||||||
- content_for :banner do
|
- content_for :banner do
|
||||||
- image = image_path(image_file || 'empty-racks.jpg')
|
- image = image_path(image_file || 'empty-racks.jpg')
|
||||||
- style = nil
|
- style = nil
|
||||||
- cover = nil
|
- cover = nil
|
||||||
- figure = nil
|
- figure = nil
|
||||||
- if capable_of(:css_mixblendmode)
|
- if capable_of(:css_mixblendmode)
|
||||||
- cover = "<div class=\"cover\" style=\"background-image: url(#{image})\"></div>"
|
- cover = "<div class=\"cover\" style=\"background-image: url(#{image})\"></div>"
|
||||||
- else
|
- else
|
||||||
- style = "background-image: url(#{image})"
|
- style = "background-image: url(#{image})"
|
||||||
#header-title.short{style: style}
|
#header-title.short{style: style}
|
||||||
= (render banner_image, {:image => image}) if defined?(banner_image) == "local-variable"
|
= (render banner_image, {:image => image}) if defined?(banner_image) == "local-variable"
|
||||||
= cover.html_safe if cover
|
= cover.html_safe if cover
|
||||||
- if @page_title.present? || defined?(page_group)
|
- if @page_title.present? || defined?(page_group)
|
||||||
- content_for :title do
|
- 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}")
|
= I18n.t(@page_title || "page_titles.#{page_group.to_s}.#{page_key.to_s}", @page_title_vars)
|
||||||
= row do
|
= row do
|
||||||
= columns do
|
= columns do
|
||||||
%h1=_(@main_title || "page_titles.#{page_group.to_s}.#{page_key.to_s}", :t, @main_title_vars)
|
%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
|
- content_for :og_image do
|
||||||
= image
|
= image
|
||||||
|
@ -1,17 +1,5 @@
|
|||||||
- this_is_the_front_page
|
- content_for :og_image do
|
||||||
- if @conference
|
= @conference.poster.full.url || image_path('default_poster.jpg')
|
||||||
= render 'conferences/header'
|
- if @conferences
|
||||||
%article
|
- @conferences.each do | conference |
|
||||||
= row do
|
= render 'conferences/conference', conference: conference, links: [ :read_more, :register ]
|
||||||
= 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 })
|
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
= render :partial => 'application/header', :locals => {:image_file => @banner_image || 'grafitti.jpg'}
|
= render :partial => 'application/header', :locals => {:image_file => @banner_image || 'grafitti.jpg'}
|
||||||
%article
|
%article
|
||||||
= row do
|
= row do
|
||||||
= columns do
|
= columns do
|
||||||
- if logged_in?
|
- if logged_in?
|
||||||
%h2=_'articles.user_settings.headings.Your_Account'
|
%h2=_'articles.user_settings.headings.Your_Account'
|
||||||
- if @conference.present? && (@conference.registration_status == :pre || @conference.registration_status == :open)
|
- if @conference.present? && (@conference.registration_status == :pre || @conference.registration_status == :open)
|
||||||
%p=_'articles.user_settings.paragraphs.conference_registration', :t
|
%p=_'articles.user_settings.paragraphs.conference_registration', :t
|
||||||
= link_to (_'actions.conference.edit_registration'), register_path(@conference.slug), class: :button
|
= link_to (_'actions.conference.edit_registration'), register_path(@conference.slug), class: :button
|
||||||
- if @conferences.present?
|
- if @conferences.present?
|
||||||
%h3=_'articles.user_settings.headings.Your_Conferences'
|
%h3=_'articles.user_settings.headings.Your_Conferences'
|
||||||
.link-dump
|
.link-dump
|
||||||
- @conferences.each do | conference |
|
- @conferences.each do | conference |
|
||||||
= link_to (_!conference.title), administration_step_path(conference.slug, :edit), class: :button
|
= link_to (_!conference.title), administration_step_path(conference.slug, :edit), class: :button
|
||||||
|
|
||||||
= form_tag update_settings_path do
|
= form_tag update_settings_path do
|
||||||
= textfield :name, current_user.name, required: true, heading: 'articles.conference_registration.headings.name', big: true
|
= 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'
|
= 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'
|
= 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
|
= 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
|
.actions
|
||||||
= button_tag :save, value: :save
|
= button_tag :save, value: :save
|
||||||
- else
|
- else
|
||||||
%h2=_'forms.actions.generic.login'
|
%h2=_'forms.actions.generic.login'
|
||||||
= render 'login'
|
= render 'login'
|
@ -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
|
||||||
|
|
23
app/views/conference_administration/_broadcast.html.haml
Normal 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
|
17
app/views/conference_administration/_dates.html.haml
Normal 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
|
@ -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
|
41
app/views/conference_administration/_events.html.haml
Normal 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?
|
11
app/views/conference_administration/_hosts_table.html.haml
Normal 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)
|
10
app/views/conference_administration/_housing.html.haml
Normal 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]
|
42
app/views/conference_administration/_locations.html.haml
Normal 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
|
35
app/views/conference_administration/_meals.html.haml
Normal 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'
|
@ -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
|
8
app/views/conference_administration/_paypal.html.haml
Normal 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
|
5
app/views/conference_administration/_poster.html.haml
Normal 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'
|
2
app/views/conference_administration/_providers.html.haml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
= columns(medium: 12) do
|
||||||
|
TO COME
|
@ -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
|
@ -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
|
17
app/views/conference_administration/_registrations.html.haml
Normal 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
|
85
app/views/conference_administration/_schedule.html.haml
Normal 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
|
@ -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
|
21
app/views/conference_administration/_stats.html.haml
Normal 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]
|
@ -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
|