diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss
index 0915f6f..4fca4e6 100644
--- a/app/assets/stylesheets/_application.scss
+++ b/app/assets/stylesheets/_application.scss
@@ -530,10 +530,6 @@ button,
#main &[type="submit"] {
background-color: $colour-5;
-
- &[value="send"] {
- background-color: $colour-4;
- }
}
&.register {
@@ -553,6 +549,11 @@ button,
background-color: $red;
}
+ &.warning,
+ #main &.warning {
+ background-color: $orange;
+ }
+
&.subdued, #main &.subdued {
background-color: #888;
}
@@ -647,7 +648,7 @@ button,
display: flex;
text-align: right;
justify-content: center;
- flex-wrap: wrap;
+ @include _(flex-wrap, wrap);
button, .button {
margin: 0.333em;
@@ -2418,8 +2419,9 @@ a.logo {
margin: 0;
.title {
+ @include _(flex, 1);
font-size: 5vw;
- margin: 1em auto 0;
+ margin: 0;
h1, h2 {
margin: 0;
@@ -2439,6 +2441,19 @@ a.logo {
max-width: 100%;
margin-top: 2em;
}
+
+ figure {
+ margin: 0;
+ }
+
+ .register-link {
+ font-size: 1.25em;
+ margin: 0.5em;
+
+ .button {
+ @include _(animation, radiate 2s linear infinite alternate);
+ }
+ }
}
.conference-details {
@@ -2941,6 +2956,10 @@ body {
to { background-position: 60px 30px; }
}
+@include keyframes(radiate) {
+ to { background-color: $green; }
+}
+
html :focus {
outline: 0;
}
@@ -3608,6 +3627,8 @@ body.policy .policy-agreement ul {
}
.conference-banner {
+ @include _-(display, flex);
+ @include _(flex-wrap, wrap);
margin: 0 auto;
width: 100%;
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 2ae5dcf..10b78b0 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -96,26 +96,29 @@ class ApplicationController < BaseController
logger.info "A JavaScript error has occurred on #{params[:location]}:#{params[:lineNumber]}: #{params[:message]}"
if Rails.env.preview? || Rails.env.production?
- request_info = {
- 'remote_ip' => request.remote_ip,
- 'uuid' => request.uuid,
- 'original_url' => request.original_url,
- 'env' => Hash.new
- }
- request.env.each do |key, value|
- request_info['env'][key.to_s] = value.to_s
- end
+ # don't worry about bots
+ unless request.user_agent =~ /Googlebot/
+ request_info = {
+ 'remote_ip' => request.remote_ip,
+ 'uuid' => request.uuid,
+ 'original_url' => request.original_url,
+ 'env' => Hash.new
+ }
+ request.env.each do |key, value|
+ request_info['env'][key.to_s] = value.to_s
+ end
- send_mail(:error_report,
- "A JavaScript error has occurred",
- report,
- params[:message],
- nil,
- request_info,
- params,
- current_user,
- Time.now.strftime("%d/%m/%Y %H:%M")
- )
+ send_mail(:error_report,
+ "A JavaScript error has occurred",
+ report,
+ params[:message],
+ nil,
+ request_info,
+ params,
+ current_user,
+ Time.now.strftime("%d/%m/%Y %H:%M")
+ )
+ end
end
rescue Exception => exception2
logger.info exception2.to_s
diff --git a/app/controllers/conference_administration_controller.rb b/app/controllers/conference_administration_controller.rb
index 640273b..f0cd794 100644
--- a/app/controllers/conference_administration_controller.rb
+++ b/app/controllers/conference_administration_controller.rb
@@ -1095,7 +1095,7 @@ class ConferenceAdministrationController < ApplicationController
do_404
end
- return true
+ return nil
end
def admin_update_housing
@@ -1155,7 +1155,7 @@ class ConferenceAdministrationController < ApplicationController
)
end
redirect_to administration_step_path(@this_conference.slug, :broadcast_sent)
- return true
+ return nil
elsif params[:button] == 'preview'
@send_to_count = view_context.broadcast_to(@send_to).size
@broadcast_step = :preview
@@ -1170,7 +1170,7 @@ class ConferenceAdministrationController < ApplicationController
)
@send_to_count = view_context.broadcast_to(@send_to).size
end
- return false
+ return true
end
def admin_update_locations
diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb
index 3e8881f..57d59b8 100644
--- a/app/helpers/admin_helper.rb
+++ b/app/helpers/admin_helper.rb
@@ -50,7 +50,8 @@ module AdminHelper
def administration_sub_steps
{
location_edit: :locations,
- event_edit: :events
+ event_edit: :events,
+ broadcast_sent: :broadcast
}
end
diff --git a/app/views/application/user_settings.html.haml b/app/views/application/user_settings.html.haml
index 3271df8..11db2c4 100644
--- a/app/views/application/user_settings.html.haml
+++ b/app/views/application/user_settings.html.haml
@@ -1,4 +1,4 @@
-= render :partial => 'application/header', :locals => {:image_file => @banner_image || 'grafitti.jpg'}
+= render partial: 'application/header', locals: {image_file: @banner_image || 'grafitti.jpg'}
%article
= row do
= columns do
@@ -18,7 +18,7 @@
= checkboxes :languages, User.AVAILABLE_LANGUAGES, (current_user.languages || [I18n.locale]).map(&:to_sym), 'languages', heading: 'articles.conference_registration.headings.languages'
= radiobuttons :preferred_language, I18n.backend.enabled_locales, current_user.locale || I18n.locale, 'languages', heading: 'articles.conference_registration.headings.preferred_language'
= checkbox :email_subscribe, current_user.is_subscribed != false, 'articles.user_settings.email_subscribe', heading: 'articles.user_settings.headings.email_subscribe', help: 'articles.user_settings.paragraphs.email_subscribe', inline: true, right_help: true
- .actions
+ .actions.center
= button :save, value: :save
- else
%h2=_'forms.actions.generic.login'
diff --git a/app/views/conference_administration/_administrators.html.haml b/app/views/conference_administration/_administrators.html.haml
index 36a2b04..157cd25 100644
--- a/app/views/conference_administration/_administrators.html.haml
+++ b/app/views/conference_administration/_administrators.html.haml
@@ -1,4 +1,19 @@
= columns(large: 8, push: { large: 2}) do
+ %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 :remove_member, value: :remove_administrator, class: [:small, :delete]
+ = admin_update_form class: 'mini-flex-form' do
+ = userfield :email, nil, required: true
+ = button :add_member, value: :add_administrator, class: :small
+
%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
@@ -22,20 +37,5 @@
= emailfield :email, nil, required: true
= button :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 :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 :add_member, value: :add_administrator, class: :small
= columns(large: 2) do
diff --git a/app/views/conference_administration/_broadcast.html.haml b/app/views/conference_administration/_broadcast.html.haml
index c1cc9b0..29d3cb7 100644
--- a/app/views/conference_administration/_broadcast.html.haml
+++ b/app/views/conference_administration/_broadcast.html.haml
@@ -1,23 +1,26 @@
-= 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
+= 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
+ = columns(medium: 12) do
- if @broadcast_step == :preview
- %p= _'articles.conference_registration.paragraphs.admin.broadcast.test', vars: { send_to_count: "#{(@send_to_count || 0)}".html_safe }
+ %p= (_'articles.conference_registration.paragraphs.admin.broadcast.test', vars: { send_to_count: "#{(@send_to_count || 0)}".html_safe }).html_safe
- else
- .warning-info.make-room= _'articles.conference_registration.paragraphs.admin.broadcast.preview', vars: { send_to_count: "#{(@send_to_count || 0)}".html_safe }
+ .warning-info.make-room=(_'articles.conference_registration.paragraphs.admin.broadcast.preview', vars: { send_to_count: "#{(@send_to_count || 0)}".html_safe }).html_safe
+ = columns(medium: 10, push: { medium: 1 }) do
.test-preview
%h3=@subject
= richtext @body, 4
- .actions.right
- = button :test, value: :test, class: :secondary if @broadcast_step == :preview
- = button_with_confirmation :send, (_'modals.admin.broadcast.confirm', vars: { number: "#{(@send_to_count || 0)}".html_safe }), value: :send, class: :delete if @broadcast_step == :test
+ = columns(medium: 12) do
+ .actions.center
+ = button :test, value: :test, class: :warning if @broadcast_step == :preview
+ = button_with_confirmation :send, (_'modals.admin.broadcast.confirm', vars: { number: "#{(@send_to_count || 0)}".html_safe }).html_safe, value: :send, class: :delete if @broadcast_step == :test
= button :edit, value: :edit
- - else
+ - else
+ = columns(medium: 12) do
= 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
+ .actions.center
= button :preview, value: :preview
diff --git a/app/views/conference_administration/_publish_schedule.html.haml b/app/views/conference_administration/_publish_schedule.html.haml
index 762ad70..2a05f64 100644
--- a/app/views/conference_administration/_publish_schedule.html.haml
+++ b/app/views/conference_administration/_publish_schedule.html.haml
@@ -2,7 +2,7 @@
= 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 :un_publish, value: :publish, class: :delete
+ .actions.center= button :un_publish, value: :publish, class: :delete
- else
%p=_'articles.conference_registration.paragraphs.admin.schedule.un_published', :p
- .actions= button :publish, value: :publish
+ .actions.center= button :publish, value: :publish
diff --git a/app/views/conferences/_conference.html.haml b/app/views/conferences/_conference.html.haml
index 4b70938..12a762b 100644
--- a/app/views/conferences/_conference.html.haml
+++ b/app/views/conferences/_conference.html.haml
@@ -1,5 +1,6 @@
- links ||= [ :register ]
- sections ||= [ :info ]
+- is_registered = conference.registered?(current_user)
= row(tag: :header) do
= columns(class: 'conference-banner') do
.title
@@ -9,8 +10,11 @@
- if conference.start_date.present? && conference.end_date.present?
.secondary
= date_span(conference.start_date.to_date, conference.end_date.to_date)
+ .register-link
+ = (link_to (_'forms.actions.generic.register'), register_path(conference.slug), class: [:button, :register]) if links.include?(:register) && conference.can_register?
- if conference.poster.present?
- %img{src: conference.poster.full.url, role: :presentation, alt: (_'images.conference.poster', vars: { conference_title: conference.title })}
+ %figure
+ %img{src: conference.poster.full.url, role: :presentation, alt: (_'images.conference.poster', vars: { conference_title: conference.title })}
%article
= row(class: 'conference-details') do
= columns(medium: 10, push: {medium: 1}) do
@@ -19,8 +23,14 @@
- conference.extended_details.each do |section|
- if sections.include?(section) && conference.copy_data[section][:show]
%h3=(_ conference.copy_data[section][:heading], vars: conference.copy_data[section][:vars]) unless conference.copy_data[section][:heading] == false
- = richtext conference.copy_data[section][:value]
+ = richtext conference.copy_data[section][:value], (conference.copy_data[section][:heading] == false ? 2 : 3)
+ .links
+ = (link_to (_(is_registered ? 'actions.conference.edit_registration' : 'forms.actions.generic.register')), register_path(conference.slug), class: [:button, :register]) if links.include?(:register) && conference.can_register?
+ = (link_to (_'articles.workshops.info.read_more'), conference_path(conference.slug), class: :button) if links.include?(:read_more)
+ = (link_to (_'forms.actions.generic.administrate'), administrate_conference_path(conference.slug), class: [:button]) if links.include?(:administrate)
+ = (link_to (_'forms.actions.generic.edit'), edit_conference_path(conference.slug), class: [:button, :subdued]) if links.include?(:edit)
+
- if conference.registration_status == :open && sections.include?(:workshops)
- if conference.workshop_schedule_published
- add_inline_script :home_schedule
@@ -30,9 +40,6 @@
%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 })
- .links
- = (link_to (_'forms.actions.generic.register'), register_path(conference.slug), class: [:button, :register]) if links.include?(:register) && conference.can_register?
- = (link_to (_'articles.workshops.info.read_more'), conference_path(conference.slug), class: :button) if links.include?(:read_more)
- = (link_to (_'forms.actions.generic.administrate'), administrate_conference_path(conference.slug), class: [:button]) if links.include?(:administrate)
- = (link_to (_'forms.actions.generic.edit'), edit_conference_path(conference.slug), class: [:button, :subdued]) if links.include?(:edit)
+ .actions.center
+ = link_to (_'actions.workshops.create'), create_workshop_path(conference.slug), class: [:button, :modify]
diff --git a/app/views/conferences/view.html.haml b/app/views/conferences/view.html.haml
index 72fa706..c7ff8c8 100644
--- a/app/views/conferences/view.html.haml
+++ b/app/views/conferences/view.html.haml
@@ -2,4 +2,4 @@
= @this_conference.poster.full.url || image_path('default_poster.jpg')
- content_for :title do
=@this_conference.title
-= render 'conferences/conference', conference: @this_conference, links: @links, sections: [:info] + @this_conference.extended_details + [:workshops]
+= render 'conferences/conference', conference: @this_conference, links: @links, sections: [:info] + @this_conference.extended_details
diff --git a/config/locales/en.yml b/config/locales/en.yml
index cdb1f17..08cb8fe 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1321,8 +1321,8 @@ en:
events: Event saved
workshop_times: Workshop times saved
schedule: Schedule updated
- publish_schedule: Your schedule has been published
- unpublish_schedule: Your schedule has been un-published
+ schedule_published: Your schedule has been published
+ schedule_unpublished: Your schedule has been un-published
org_member_added: User added to organization
org_member_removed: User removed from organization
administrator_added: Administrator added to conference
@@ -1384,7 +1384,7 @@ en:
back: Back to Administration
paragraphs:
administration: From this dashboard you can configure your conference details,
- open registration, view statictics, compile your workshop scheulde, and
+ open registration, view statistics, compile your workshop schedule, and
more.
stats:
description: On this page you can view a breakdown of the registration process
@@ -1395,7 +1395,7 @@ en:
donation_count: Number of donations
donation_total: Total donated
food:
- meat: Onmivores
+ meat: Omnivores
vegetarian: Vegetarians
vegan: Vegans
registrations: Number of registrations
@@ -1408,7 +1408,7 @@ en:
heading: Meals
events:
description: On this page you can schedule events. Events are any type of
- event that isn't a meal or a workshop. You can scheulde group meetings,
+ event that isn't a meal or a workshop. You can schedule group meetings,
parties, or group ride for example.
no_locations_warning: Before you can add events, you must first add locations.
heading: Events
@@ -1440,8 +1440,8 @@ en:
publish_schedule: Once you have finalized your schedule, make it public
here.
housing:
- description: Arrange housing for registratnts visiting your city. Pair each
- registratnt who has asked for housing with a registratnt that has volunteered
+ description: Arrange housing for registrants visiting your city. Pair each
+ registrant who has asked for housing with a registrant that has volunteered
to house guests base on their individual needs and wants.
heading: Housing
headings:
@@ -1509,7 +1509,7 @@ en:
administrators: Administrators and Organizations
poster: Poster
Host_Organizations: Host Organizations
- External_Administrators: External Administrators
+ External_Administrators: Conference Administrators
description: These are the basic details about your conference that you will
likely want to configure before enabling your conference. One ready, contact
the site administrator to make the conference public.
@@ -1519,13 +1519,10 @@ en:
administrators: Set the conference host organizations and other members
who have access to these administration tools
Host_Organizations: Select all organizations from known organizations in
- %{city_name} that will be helping to host your conference. All members
- of each organization will be granted access to these administration tools,
- if you require administrators that are not members of an organization,
- you can add them below. If an organization is not listed here, please
+ %{city_name}. Members of your organizations do not immediately have access to the administration tools on this site
+ You will also need to add them to to the "Conference Administrators" list above. If an organization is not listed here, please
contact a site administrator.
- External_Administrators: Users from outside of organizations in your city
- can be granted administration privledges here.
+ External_Administrators: Users from witin or outside of the host organizations that have administration privileges on this site.
copy:
heading: Site Copy
description: Copy that is displayed in the front page, the details page, emails,
@@ -1553,7 +1550,7 @@ en:
rides
travel_info: Let visitors know how to get to your city and what international
visitors may need to be prepared for
- city_info: Describe your city, talk about things like saftey, laws, weather,
+ city_info: Describe your city, talk about things like safety, laws, weather,
and culture
what_to_bring: Let visitors know what to bring
volunteering_info: Let potential volunteers know what they can do and how
@@ -1567,15 +1564,17 @@ en:
stats: Statistics
registrations: Modify Registrations
broadcast: Contact Users
+ broadcast_sent: Message Sent
description: Open or close registration, view registration statistics, modify
- information subbmitted by registratnts and contact users.
+ information submitted by registratnts and contact users.
descriptions:
registration_status: Open or close registration to your conference.
- stats: View a breakdown of statictics, how many users have registered, how
+ stats: View a breakdown of statistics, how many users have registered, how
much money have been collected, etc.
registrations: View and edit all data collected through the registration
process.
broadcast: Send emails to targeted subsets of users.
+ broadcast_sent: Your message has been sent.
broadcast:
heading: Broadcast
description: The broadcast tool is used to contact users through email. You
@@ -1584,12 +1583,12 @@ en:
description: Your message has been sent.
workshop_times:
heading: Workshop Times
- description: Before you scheulde workshops, you must first create blocks of
+ description: Before you schedule workshops, you must first create blocks of
time when the workshops will be.
payment:
heading: Payment
- description: If you wish to collect dontaions and registration fees, you will
- need to confgure your payment details
+ description: If you wish to collect donations and registration fees, you will
+ need to configure your payment details
headings:
suggested_amounts: Suggested Payment Amounts
paypal: PayPal Info
@@ -1601,7 +1600,7 @@ en:
your organization's PayPal account
contact:
headings:
- contact: Send us a question or a complement
+ contact: Send us a question or a comment
reason: What are you contacting us about?
sent: Thank you for contacting us
paragraphs:
@@ -1657,7 +1656,7 @@ en:
tent_space_required: Enter the amount of tent space you have to offer
info_required: Provide your guests with information about you and your home
policy_required: Read each statement carefully and check the box once to signify
- that you aggree to uphold the agreement.
+ that you agree to uphold the agreement.
name_required: Provide us with a name that you identify with
language_required: Select at least one language that you can speak
location_required: Enter a location
@@ -1679,7 +1678,7 @@ en:
again.
warning:
payment_pending: Thank you! Your payment is currently pending.
- companion_unregistered: Your companion has not yet registerred. Please ensure
+ companion_unregistered: Your companion has not yet registered. Please ensure
that they do to guarantee you are housed together.
step_names:
group_ride: Group ride?
@@ -1875,7 +1874,7 @@ en:
org_select: Please select the organization that you participate in. This information
will be used to help us contact and invite your organization next year and
to populate the list of known organizations that will be displayed on bikecollectives.org.
- If you are involved with multiple oganizations, please select one for now,
+ If you are involved with multiple organizations, please select one for now,
you will be able to add more organizations at a later date.
payment_type: If you can, please pay now via PayPal. We collect the registration
fee as a donation. Your donation pays for spaces, food, equipment, and much
@@ -1899,7 +1898,7 @@ en:
who you absolutely must be housed with? Please note, your companion must
also register if you want to be housed together.
housing_type: Do you need a place to stay in %{city}? We will do our best
- to place you with a local host and other vistors that best match your needs.
+ to place you with a local host and other visitors that best match your needs.
housing_departure_date: When will you be leaving %{city}? If you wish to stay
in town longer and need housing or a bike after %{max_date}, please select
this date on the calendar below and contact us after you complete your registration.
@@ -1914,7 +1913,7 @@ en:
org_create_email: In order to contact your organization next year, please
provide a general email address. We will not send you regular emails. We
may email you if there is a conference in your area or to confirm that your
- organization is still in existance. Please do not provide a personal email
+ organization is still in existence. Please do not provide a personal email
address.
org_create_address: Please enter the street address of your organization in
%{city}, do not enter the state, province, or country. If your organization
@@ -2041,16 +2040,16 @@ en:
should expect
schedule_info: Describe your schedule over the conference
travel_info: Let visitors know what to expect travelling to your city
- city_info: Let visitors knw about your city, its culture, climate, crime,
+ city_info: Let visitors know about your city, its culture, climate, crime,
and any other details that should know about
what_to_bring: List what you expect visitors to bring. Common items include
a bike helmet, lock, and eating utensils
volunteering_info: Let interested volunteers know how they can volunteer
- and what tey can do
+ and what they can do
additional_details: Let visitors know any additional information about
your conference
schedule:
- published: Your scheulde is currently published and viewable on the front-page.
+ published: Your schedule is currently published and viewable on the front-page.
Un-publishing the schedule will remove it from the front-page and show
a list of proposed workshops instead.
un_published: Your schedule is not yet published. Publishing the schedule
@@ -2123,7 +2122,7 @@ en:
paragraphs:
bicycle_project_paragraph: Community bicycle projects do many different things.
Some use bicycles to change society, the economy, or the environment. Some
- have community bike shops. Some promote bicyle use and making their communities
+ have community bike shops. Some promote bicycle use and making their communities
into places where riding is easier, more inclusive, safer, and more fun.
The list below uses the criteria found in the old Bicycle Organization Organization
Project for what constitutes a community bike shop. The bike project need
diff --git a/config/unicorn.rb b/config/unicorn.rb
index 053b03f..ebe6afc 100644
--- a/config/unicorn.rb
+++ b/config/unicorn.rb
@@ -12,6 +12,8 @@ else
port = 8080
end
+timeout 600
+
working_directory directory
# Listen on unix socket
diff --git a/features/step_definitions/users.rb b/features/step_definitions/users.rb
index 585cbd6..c4d9efc 100644
--- a/features/step_definitions/users.rb
+++ b/features/step_definitions/users.rb
@@ -67,10 +67,8 @@ end
Given /^(?:I )?am an? (.+)$/i do |role|
if role == 'conference host'
- org = TestState.last_conference.organizations.first
- org.users ||= Array.new
- org.users << TestState.my_account
- org.save
+ TestState.last_conference.administrators << TestState.my_account
+ TestState.last_conference.save!
else
case role
when /(site )?admin(istrator)?/