Skip to content

Commit

Permalink
🎉 add feedback widget feature [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
colinwilson committed Aug 13, 2023
1 parent f3f0e34 commit 675e94c
Show file tree
Hide file tree
Showing 6 changed files with 287 additions and 5 deletions.
6 changes: 3 additions & 3 deletions assets/docs/scss/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,9 @@ $stretched-link-z-index: 1;
--btn-soft-bg: none;
--btn-soft-border: var(--gray-800);

--btn-primary-color: var(--primary);
--btn-primary-bg: var(--white);
--btn-primary-border: var(--gray-200);
--btn-primary-color: var(--primary-200);
--btn-primary-bg: none;
--btn-primary-border: var(--gray-700);

--btn-default-color: var(--text-default);
--btn-default-hover-color: var(--primary-300);
Expand Down
59 changes: 59 additions & 0 deletions assets/docs/scss/custom/plugins/feedback/_feedback.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* Feedback Widget */

#feedback-init {
transition: opacity 0.5s;
}

#feedback-form-pos,
#feedback-form-neg,
#feedback-end,
#feedback-submit {
height: 0;
line-height:0;
overflow: hidden;
opacity: 0;
transition: opacity 0.5s;

&.is-visible {
height: auto;
line-height: inherit;
overflow: inherit;
opacity: 1;
}

.form-check {
margin-bottom: 0.525rem;
}

.form-check-label,
.form-check-input {
font-weight: 600;
cursor: pointer;
}
}


#feedback-submit {
&.is-visible {
opacity: 0.65;
}
}

.feedback-radio-desc {
color: var(--text-muted);
font-size: 14px;
}

.feedback-textarea {
width: 50%;
font-size: 0.875rem;
color: var(--text-default);
background: var(--card-bg);
resize: none;
border: solid 1px;
border-radius: 4px ;
border-color: var(--card-border-color);
@media (max-width:578px) {
width: 100%;
}
}
4 changes: 3 additions & 1 deletion assets/docs/scss/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ $code-block-padding-top: {{ if eq .Site.Params.docs.prism true -}}0{{ else }}1.2

// Plugins
{{ if eq .Site.Params.docs.prism true -}}@import "custom/plugins/prism/prism";{{ end }}
{{ if or (not (isset .Site.Params.flexsearch "enabled")) (eq .Site.Params.flexsearch.enabled true) -}}@import "custom/plugins/flexsearch/flexsearch";{{ end }}
{{ if or (not (isset .Site.Params.flexsearch "enabled")) (eq .Site.Params.flexsearch.enabled true) -}}@import "custom/plugins/flexsearch/flexsearch";{{ end }}

{{ if .Site.Params.feedback.enabled | default false -}}@import "custom/plugins/feedback/feedback";{{ end}}
4 changes: 4 additions & 0 deletions layouts/docs/single.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@
{{ partial (printf "%s/%s" (.Site.Params.docs.pathName | default "docs") "gitinfo") . }}
{{ end -}}

{{ if .Site.Params.feedback.enabled | default false -}}
{{- partial (printf "%s/%s" (.Site.Params.docs.pathName | default "docs") "footer/feedback.html") . -}}
{{ end -}}

{{ end }}
216 changes: 216 additions & 0 deletions layouts/partials/docs/footer/feedback.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<div id="feedback-widget" class="feedback-container pt-4">
<div id="feedback-init" class="d-flex justify-content-md-start justify-content-sm-center">
<span class="fs-5 fw-bold me-2 align-self-center">Was this page helpful?</span>
<div class="d-flex">
<button id="posBtn" class="feedback-btn btn btn-primary btn-sm me-2" type="submit">
<span class="fs-6">
<i class="material-icons size-20 me-1 align-middle">thumb_up</i>
Yes
</span>
</button>
<button id="negBtn" class="feedback-btn btn btn-primary btn-sm me-2" type="submit">
<span class="fs-6">
<i class="material-icons me-1 align-middle">thumb_down</i>
No
</span>
</button>
</div>
</div>

<div id="feedback-end" class="d-flex justify-content-md-start justify-content-sm-center fs-4 fw-bold me-2">
</div>

<div id="feedback-form-pos" data-type="positive" class="feedback-form justify-content-md-start justify-content-sm-center">
<p class="fw-bold fs-5">What did you like?</p>
<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="accurate" id="accurate">
<label class="form-check-label" for="accurate">
Accurate
</label>
<p class="feedback-radio-desc mb-0">Accurately describes the product or feature.</p>
</div>
<div id="accurateTextContainer" class="feedback-textarea-container"></div>

<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="solved" id="solved">
<label class="form-check-label" for="solved">
Solved my problem
</label>
<p class="feedback-radio-desc mb-0">Helped me resolve an issue.</p>
</div>
<div id="solvedTextContainer" class="feedback-textarea-container"></div>

<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="easy" id="easy">
<label class="form-check-label" for="easy">
Easy to understand
</label>
<p class="feedback-radio-desc mb-0">Easy to follow and comprehend.</p>
</div>
<div id="easyTextContainer" class="feedback-textarea-container"></div>

<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="other" id="otherPos">
<label class="form-check-label" for="otherPos">
Something else
</label>
</div>
<div id="otherPosTextContainer" class="feedback-textarea-container"></div>
</div>

<div id="feedback-form-neg" data-type="negative" class="feedback-form justify-content-sm-center">
<p class="fw-bold fs-5">What went wrong?</p>
<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="inaccurate" id="inaccurate">
<label class="form-check-label" for="inaccurate">
Inaccurate
</label>
<p class="feedback-radio-desc mb-0">Doesn't accurately describe the product or feature.</p>
</div>
<div id="inaccurateTextContainer" class="feedback-textarea-container"></div>

<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="missing" id="missing">
<label class="form-check-label" for="missing">
Couldn't find what I was looking for
</label>
<p class="feedback-radio-desc mb-0">Missing important information.</p>
</div>
<div id="missingTextContainer" class="feedback-textarea-container"></div>

<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="hard" id="hard">
<label class="form-check-label" for="hard">
Hard to understand
</label>
<p class="feedback-radio-desc mb-0">Too complicated or unclear.</p>
</div>
<div id="hardTextContainer" class="feedback-textarea-container"></div>

<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="errors" id="errors">
<label class="form-check-label" for="errors">
Code sample errors
</label>
<p class="feedback-radio-desc mb-0">One or more code samples are incorrect.</p>
</div>
<div id="errorsTextContainer" class="feedback-textarea-container"></div>

<div class="form-check">
<input class="form-check-input" type="radio" name="feedback" value="other" id="otherNeg">
<label class="form-check-label" for="otherNeg">
Something else
</label>
</div>
<div id="otherNegTextContainer" class="feedback-textarea-container"></div>
</div>

<button id="feedback-submit" class="feedback-submit-btn btn btn-sm btn-primary mt-3" type="submit" disabled>
<span class="fs-6">
Submit
</span>
</button>

</div>

<script>
// https://stackoverflow.com/a/29017547
const feedbackInit = document.getElementById("feedback-init");
const posBtn = document.getElementById("posBtn");
const negBtn = document.getElementById("negBtn");
const feedbackBtn = document.querySelectorAll('.feedback-btn');
const feedbackFormPos = document.getElementById("feedback-form-pos");
const feedbackFormNeg = document.getElementById("feedback-form-neg");
const feedbackSubmit = document.getElementById("feedback-submit")

// Show feedback form
feedbackBtn.forEach(btn => {
btn.addEventListener('click', event => {
const btnID = btn.id
feedbackInit.style.opacity = '0'
feedbackInit.addEventListener('transitionend', function () {
feedbackInit.remove();
if (btnID == 'posBtn') {
feedbackFormPos.classList.add("is-visible");
feedbackFormNeg.remove();
feedbackSubmit.classList.add("is-visible");
} else if (btnID == 'negBtn') {
feedbackFormNeg.classList.add("is-visible");
feedbackFormPos.remove();
feedbackSubmit.classList.add("is-visible");
}
}
);
})
});

// Add text area box to selected feedback radio
const Radios = document.querySelectorAll('input[name="feedback"]');
const textareas = document.querySelectorAll('.feedback-textarea-container');

Radios.forEach(radio => {
radio.addEventListener('change', function(event) {
const radioID = event.target.id;
const addOn = document.getElementById(radioID+"TextContainer");
// First, remove 'activeBox' class and <textarea> from all textarea containers
for (const textarea of textareas) {
textarea.classList.remove('activeBox');
while (textarea.firstChild) {
textarea.removeChild(textarea.firstChild);
}
}
addOn.innerHTML +='<textarea id="textarea" cols="55" maxlength="500" rows="3" placeholder="(Optional) Try to be as specific and detailed as possible!" type="text" class="feedback-textarea p-2 mb-2"></textarea>';
addOn.classList.add("activeBox");
feedbackSubmit.removeAttribute("disabled");
feedbackSubmit.classList.add("opacity-100");
// console.log(radioID);
});
});

feedbackSubmit.addEventListener('click', event => {
const form = document.querySelector('.feedback-form');
const formType = form.getAttribute("data-type");
const result = document.getElementById("feedback-end");
const selected = document.querySelector('input[name="feedback"]:checked').value;
const message = document.getElementById('textarea').value;
function success(e) {
form.remove();
feedbackSubmit.remove();
result.innerHTML = "Thank you for helping to improve Lotus Docs' documentation!";
result.classList.add("is-visible");
}
try {
if (formType == "positive") {
plausible('Positive Feedback',
{
callback: success,
props:
{
selection: selected,
message: message
}
}
)
} else if (formType == "negative") {
plausible('Negative Feedback',
{
callback: success,
props:
{
selection: selected,
message: message
}
}
)
}
} catch (err) {
console.log(err);
form.remove();
feedbackSubmit.remove();
result.innerHTML = "Sorry! There was an error when attempting to submit your feedback!";
result.classList.add("is-visible");
}
// console.log("feedback submitted")
});

</script>
3 changes: 2 additions & 1 deletion layouts/partials/docs/head/plausible.html
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<script defer data-domain="{{ .Site.Params.plausible.dataDomain }}" {{ if .Site.Params.plausible.eventAPI }}data-api='{{ .Site.Params.plausible.eventAPI }}/api/event'{{ end }} src='{{ .Site.Params.plausible.scriptURL | default "https://plausible.io" }}/js/script.js'></script>
<script defer data-domain="{{ .Site.Params.plausible.dataDomain }}" {{ if .Site.Params.plausible.eventAPI }}data-api='{{ .Site.Params.plausible.eventAPI }}/api/event'{{ end }} src='{{ .Site.Params.plausible.scriptURL | default "https://plausible.io" }}/js/script.js'></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>

0 comments on commit 675e94c

Please sign in to comment.