Skip to content

Instantly share code, notes, and snippets.

@badlydrawnrob
Last active December 7, 2023 15:19
Show Gist options
  • Save badlydrawnrob/06486b02f1c5cd1e2901 to your computer and use it in GitHub Desktop.
Save badlydrawnrob/06486b02f1c5cd1e2901 to your computer and use it in GitHub Desktop.
Counselling Anywhere search results folder
// Homepage search =============================
// - #1: Example of column > row stacking:
// http://codepen.io/HugoGiraudel/pen/pkwqH
// - #2: Remove `overflow:hidden` to align input with button
// - #3: flex: 0 1 100%; breaks layout on mobile safari
// width: 100% is required for some reason!
@selectize-color-border: @color-primary;
@selectize-color-item-active-border: @color-primary;
@selectize-border-radius: 0;
@selectize-font-size: inherit;
@selectize-line-height: inherit;
.sf {
display: flex;
flex-flow: row wrap;
flex-direction: column; // #1
justify-content: space-between;
@media (min-width: @screen-sm-min) {
flex-direction: row;
}
}
.sf-Selectize {
width: 100%; // #3
font-size: inherit;
.selectize-input {
.to-rem(padding, @btn-padding);
overflow: visible; // #2
}
@media (min-width: @screen-sm-min) {
margin: 0;
flex-basis: 70%;
}
}
.sf-Button {
width: 100%; // #3
font-size: inherit;
@media (min-width: @screen-sm-min) {
flex: 0 1 30%;
}
}
.sf-FormGroup {
width: 100%; // #3
font-size: inherit;
@media (min-width: @screen-sm-min) {
flex: 0 1 22%;
}
.articles & {
.vh();
}
}
.sf-FormLabel {
display: inline-block;
padding-right: 2%;
}
.sf-Wrapper {
.to-rem(margin-top, @spacing-base);
.to-rem(border-top, 1, solid fade(#000, 15%));
.articles & {
.vh();
}
}
.sf-ButtonSmall {
flex: none;
margin-right: auto; // compensate for justify-content
}
{#
# Search form include template
# ----------------------------
#
# - Using Selectize plugin
# - 1: Label order doesn't matter: http://bit.ly/1ouINj8
# - 2: `disabled` won't post `gender` parameter :)
# - 3: Number attributes: http://bit.ly/1mdevQx
#}
{% set searchbox %}
{% set users = craft.config.devMode or craft.config.development
? craft.users.group('testing')
: craft.users.group('verified') %}
{% set tags = craft.tags.group('condition').relatedTo(users).limit(0) %}
<select class="sf-Selectize" name="tags">
<option value="">We're here to help you with ... (eg: anxiety)</option>
{% for tag in tags %}
<option value="{{ tag.slug }}">
{{- tag.title -}}
</option>
{% endfor %}
</select>
<input class="sf-Button btn btn-primary mb- sm-m0" type="submit" value="Search">
{% endset %}
{% set searchOptions %}
{% set selectGender = craft.fields.getFieldByHandle('gender') %}
{% set selectSessions = craft.categories.group('sessions') %}
{% set selectHours = craft.categories.group('hours') %}
<div class="sf-FormGroup form-group mt-">
<label for="gender">
<small>Gender of Therapist:</small> {# 1 #}
</label>
<select class="form-select" id="gender" name="gender"> {# 2 #}
{% for option in selectGender.settings.options %}
{% if not option.value|length %}
<option disabled selected>{{ option.label }}</option>
{% else %}
<option value="{{ option.value }}">{{ option.label }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="sf-FormGroup form-group mt-"> {# 3 #}
<label class="" for="maxPrice">
<small>Maximum session price:</small>
</label>
<input class="form-input" id="maxPrice" type="number" name="maxPrice"
min="0" max="100" step="5">
</div>
<div class="sf-FormGroup form-group mt-">
<label class="db" for="maxPrice">
<small>Session type (please select one):</small>
</label>
{% for category in selectSessions %}
<label class="sf-FormLabel">
<input class="form-control" type="checkbox" value="{{ category.slug }}"
name="sessions[]"> {{ category.title }}
</label>
{% endfor %}
</div>
<div class="sf-FormGroup form-group mt-">
<label class="db" for="maxPrice">
<small>Hours available (please select one):</small>
</label>
{% for category in selectHours %}
<label class="sf-FormLabel">
<input class="form-control" type="checkbox" value="{{ category.slug }}"
name="hours[]"> {{ category.title }}
</label>
{% endfor %}
</div>
{% endset %}
<form class="sf mv sm-mb+" action="{{ url('search/results') }}">
{% cache globally %}
{{ searchbox }}
{{ searchOptions }}
{% endcache %}
<div class="sf-Wrapper wrapper wrapper-flush">
<!-- <a class="btn btn-sm mt mr" href="{# siteUrl #}profiles/all/">
<i class="fa fa-users"></i> View all counsellors
</a> -->
<a class="sf-ButtonSmall btn btn-sm mt" href="{{ siteUrl }}search/tags/">
<i class="fa fa-tags"></i> View all conditions
</a>
</div>
</form>
.search {
// Tags list page
.wrapper-full-bleed {
background: fade(@color-secondary, 65%);
}
}
.sr-Filters {
}
.sr-Filters_Button {
box-shadow: 0 0 0 1px fade(#000, 20%);
}
.sr-Counsellor {
.to-rem(border-bottom, @hr-border-width, @hr-border-style @hr-border-color);
&-featured,
&:last-child {
border-bottom: none;
}
&-featured .btn {
box-shadow: 0 0 0 1px fade(#000, 20%);
}
}
.sr-Counsellor_Tags {
.to-rem(padding, @spacing-base);
list-style: none;
background: @color-secondary;
}
.sr-Counsellor_TagsItem {
display: inline-block;
&-specialism {
font-weight: bold;
}
}
{#
# Tags list include template
# --------------------------
#}
{% set users = craft.users.group('verified') %}
{% set tags = craft.tags.group('condition').relatedTo(users).limit(0) %}
<ul class="tags-list list-inline">
{% for tag in tags %}
<li class="pr">
{% if currentUser and currentUser.admin %}
<ul>
<li>
<a href="{{ siteUrl }}search/results?tags={{ tag.slug }}">
{{- tag.title -}}
</a>
</li>
<li><code>{{- tag.slug -}}</code></li>
</ul>
{% else %}
<a href="{{ siteUrl }}search/results?tags={{ tag.slug }}">
{{- tag.title -}}
</a>
{% endif %}
</li>
{% endfor %}
</ul>
{#
# Search template
# ---------------
# - helpers:
# Test users: http://bit.ly/1UmUQuB (edit: http://bit.ly/1p8W2Ge)
# - Notes:
#
# 1: Set general criteria (array)
# 2: Set relations criteria (array)
# 3: We could also use a loop here for multiple tags: http://bit.ly/1KEIf4b
# - Changed `.ids()` to `.first()` to give single result.
# 4: Use `is defined` to see if 'key' exists: http://bit.ly/1SCJVxp
# - Eventually it might be better to use this method in general,
# so we don't have to add params if they're not wanted.
# - Although, I think this is only possible with javascript
# - param is posted even if value is empty
# - `disabled` won't post `name` however
# 5: != Should these not be written 'key': 'value'?
# 6: Prepare criteria model
# - Returning the user array, 2 options:
# 7: Implicit: |length (using)
# Explicit: set users = users.find()
# - Other Notes:
#
# For relatedTo params, we only need to add them if they have values
# - see: http://bit.ly/1Zzi9AL,
# http://bit.ly/1V669Fx,
# and http://bit.ly/1Pf2aIx
# 2 methods to merge `request.sessions`, without the for loop we'd have
# 'and', { targetElement: ['123', '124'] }
# - This would give 'or' conditions. We want 'and' conditions.
-#}
{% extends '_layout' %}
{% block content %}
<div class="wrapper mt">
<div class="grid">
<div class="grid-item 1/1">
<h1>Search Results</h1>
{% set request = craft.request.getQuery() %}
{# 1 #}
{% set param = {
order: 'RAND()',
limit: null,
} %}
{% set param = craft.config.devMode or craft.config.development
? param|merge({ group: 'testing' })
: param|merge({ group: 'verified' }) %}
{# 2 #}
{% set relatedToParam = ['and'] %}
{# 3 #}
{% if request.tags %}
{% set tag = craft.tags.group('condition').slug(request.tags).first() %}
{% set relatedToParam = relatedToParam|merge([{
targetElement: tag.id,
field: 'tagsSpecialism',
}]) %}
{% endif %}
{# 4, 5 #}
{% if request.gender is defined %}
{% set param = param|merge({ gender: request.gender }) %}
{% endif %}
{% if (request.maxPrice is defined) and (request.maxPrice|length) %}
{% set param = param|merge({
profilePricingSession: [
'and',
'> 0',
"<= #{request.maxPrice}"
],
}) %}
{% endif %}
{% if request.sessions is defined %}
{% for slug in request.sessions %}
{% set catIds = craft.categories.group('sessions').slug(slug).ids() %}
{% if catIds %}
{% set relatedToParam = relatedToParam|merge([{ targetElement: catIds }]) %}
{% endif %}
{% endfor %}
{% endif %}
{% if request.hours is defined %}
{% for slug in request.hours %}
{% set catIds = craft.categories.group('hours').slug(slug).ids() %}
{% if catIds %}
{% set relatedToParam = relatedToParam|merge([{ targetElement: catIds }]) %}
{% endif %}
{% endfor %}
{% endif %}
{% if relatedToParam|length > 1 %}
{% set param = param|merge({ relatedTo: relatedToParam }) %}
{% endif %}
{# 6 #}
{% set users = craft.users(param) %}
{#
# Grouping:
# ------------------------------------------------------------------ #}
{% set resultWithSpecialism = [] %}
{% set resultWithoutSpecialism = [] %}
{% for user in users %}
{% set specialismTags = user.tagsSpecialismSearchable %}
{% set specialisms = specialismTags|split(', ') %}
{% if request.tags %}
{% if tag.title in specialisms %}
{% set resultWithSpecialism = resultWithSpecialism|merge([user]) %}
{% else %}
{% set resultWithoutSpecialism = resultWithoutSpecialism|merge([user]) %}
{% endif %}
{% endif %}
{% endfor %}
{#
# Filter options:
# ------------------------------------------------------------------ #}
{% set resultsOptions %}
<div class="sr-Filters box mb">
<h4><strong>Your filters:</strong></h4>
<ul class="list-inline">
{% if request.gender is defined %}
<li><strong>Gender of Therapist: </strong> {{ request.gender }}</li>
{% endif %}
{% if (request.maxPrice is defined) and (request.maxPrice|length) %}
<li>
<strong>Maximum session price: </strong>
{{ request.maxPrice|currency('GBP') }}
</li>
{% endif %}
{% if request.sessions is defined %}
<li>
<strong>Session type: </strong>
{% for session in request.sessions %}
{{ session }}{{ not loop.last ? ', ' }}
{% endfor %}
</li>
{% endif %}
{% if request.hours is defined %}
<li>
<strong>Hours available: </strong>
{% for time in request.hours %}
{{ time }}{{ not loop.last ? ', ' }}
{% endfor %}
</li>
{% endif %}
</ul>
<p><a class="sr-Filters_Button btn" href="{{ siteUrl }}">Change your search options</a></p>
</div>
{% if request.tags %}
<p class="entry-intro">
Your search for "<strong>{{ tag.title }}</strong>", returned <strong>{{ users|length }}</strong> counsellors:
</p>
{% else %}
<p class="box error">It appears you didn't <strong>select a condition</strong>. Please select one, then <a href="{{ siteUrl }}">search again</a></p>
{% endif %}
{% endset %}
{#
# Return results:
# ------------------------------------------------------------------
# - 7: Using this option
#}
{% if users|length %}
{{ resultsOptions }}
{% if resultWithSpecialism|length %}
{% for user in resultWithSpecialism %}
<div class="sr-Counsellor-featured mb pb">
<div class="box">
<div><img class="gl-Img-circle" src="{{ user.photoUrl }}" alt=""></div>
<h2>{{ user.fullName }}</h2>
<div>{{ user.intro }}</div>
<div><a class="btn" href="/profiles/{{ user.username }}">View counsellor</a></div>
</div>
{% if currentUser and currentUser.admin %}
<ul class="sr-Counsellor_Tags">
{% for tag in user.tagsSpecialism %}
<li class="sr-Counsellor_TagsItem{{ loop.index <= 5 ? ' sr-Counsellor_TagsItem-specialism'}}">
{{ tag.title }}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
{% endif %}
{% if resultWithoutSpecialism|length %}
{% for user in resultWithoutSpecialism %}
<div class="sr-Counsellor mb pb">
<div><img class="gl-Img-circle" src="{{ user.photoUrl }}" alt=""></div>
<h2>{{ user.fullName }}</h2>
<div>{{ user.intro }}</div>
<div><a class="btn" href="/profiles/{{ user.username }}">View counsellor</a></div>
{% if currentUser and currentUser.admin %}
<ul class="sr-Counsellor_Tags">
{% for tag in user.tagsSpecialism %}
<li class="sr-Counsellor_TagsItem{{ loop.index <= 5 ? ' sr-Counsellor_TagsItem-specialism'}}">
{{ tag.title }}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
{% endif %}
{% else %}
{{ resultsOptions }}
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% extends '_layout' %}
{% set title = 'Select a condition from the list' %}
{% block content %}
<div class="wrapper wrapper-full-bleed pv">
<div class="wrapper">
<div class="grid">
<div class="grid-item 1/1">
<h1>{{ title }}</h1>
<div class="entry-intro">
{% include 'search/_tags.twig' %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment