Hoekstra_VFZ
3 years agoAdvisor
Topic Progress Bar
Hi,
We have a use case where we want to communicate to new users on our forum what happens if they ask a question, and what is their Next Best Action in case no one replies. Also if a visitor is not the Topicstarter we want to communicatie their Next Best Action is to help get an answer.
Together with a selected group of users we came up with a Topic progress bar that is visible on the PostPage and on ForumTopicPages (only in our coreNode Support)
See it in action in this forum board:
https://community.ziggo.nl/t5/Internet/bd-p/Internet
We would to share this component with anyone who is interesed. Any feedback on the code? Or going to use this on your Community? Please let me know in this topic.
<#-------------------- COMPONENT ---------------------
Topic Progress Bar v1
----------------------------------------------------
Scope: postpage, forumtopicpage
Instance: N/A
Created By: Anne Hoekstra
Last Modified By: Anne Hoekstra
Last Modified Date: 29-06-2022
Last Reviewed By: N/A
Last Reviewed Date: N/A
----------------------------------------------------->
<#-------------------- MANIFEST ----------------------
Functions:
- dateOffset
Key documentation used:
-
----------------------------------------------------->
<#-------------------- DEFAULT CONTENT -------------->
<#assign tooltip_text = "Omschrijf je vraag, wacht op reacties en krijg de oplossing." />
<#assign fase1_class = "current" />
<#assign fase2_class = "next" />
<#assign fase3_class = "next" />
<#assign fase1_text = "Start je topic" />
<#assign fase2_text = "Reacties" />
<#assign fase3_text = "Oplossing" />
<#assign show_tipLink = false />
<#assign tipLink = "https://community.ziggo.nl/t5/Over-de-Community/Zo-krijg-je-antwoord-op-je-vraag/td-p/996645" />
<#-------------------- IMPORT DEPENDENCIES ---------->
<#import "theme-lib.common-functions.ftl" as commonUtils />
<#-------------------- FUNCTIONS -------------------->
<#-- dateOffset - This function adds days to a timestamp -->
<#function dateOffset date days>
<#assign timeInMillisecond = (1000 * 60 * 60 * 24 * days) />
<#assign aDate = date?long + timeInMillisecond?long />
<#return aDate?number_to_datetime>
</#function>
<#-------------------- BASE DATA -------------------->
<#attempt>
<#assign currentDateTime = .now />
<#assign slaDays = 2 />
<#assign nonTSreplies = 0 />
<#assign currentUser = "visitor" />
<#if page.name == "ForumTopicPage">
<#assign threadId = page.context.thread.topicMessage.uniqueId />
<#assign threadInfo = "SELECT id, post_time, post_time_friendly, conversation.last_post_time, conversation.last_post_time_friendly, author.id, author.login, read_only, replies.count(*), conversation.solved FROM messages WHERE topic.id = '${threadId}' ORDER BY post_time ASC" />
<#assign solutionInfo = "SELECT id, view_href FROM messages WHERE topic.id = '${threadId}' AND is_solution = true ORDER BY post_time ASC LIMIT 1" />
<#assign topicData = commonUtils.executeLiQLQuery(threadInfo) />
<#assign solutionData = commonUtils.executeLiQLQuery(solutionInfo) />
</#if>
<#if topicData?has_content>
<#assign topic_has_solution = topicData[0].conversation.solved />
<#assign topic_author_id = topicData[0].author.id />
<#assign topicDateTime = topicData[0].post_time?datetime />
<#assign lastpostDateTime = topicData[0].conversation.last_post_time?datetime />
<#assign slaDateTime = dateOffset(topicDateTime, slaDays) />
<#if (currentDateTime?datetime > slaDateTime?datetime) >
<#assign withinSLA = false />
<#else>
<#assign withinSLA = true />
</#if>
<#if !user.anonymous >
<#assign currentUser = "member" />
<#if user.id?c == topic_author_id >
<#assign currentUser = "topicstarter" />
</#if>
</#if>
<#list topicData as data>
<#if data.author.id != topic_author_id >
<#assign nonTSreplies += 1 />
</#if>
</#list>
</#if>
<#if solutionData?has_content>
<#assign solutionLink = solutionData[0].view_href>
</#if>
<#recover>
</#attempt>
<#-------------------- DYNAMIC CONTENT -------------->
<#attempt>
<#if page.name == "ForumTopicPage" && topicData?has_content >
<#assign fase1_text = "Vraag" />
<#-- following tooltip is a fallback, if this shows something is broken -->
<#assign tooltip_text = "Status van dit topic - Reageer en help mee. Samen weten we meer." />
<#if topic_has_solution == true >
<#assign tooltip_text = "Status van dit topic - De vraag is beantwoord." />
<#else>
<#if currentUser == "member" && (nonTSreplies > 0) >
<#assign fase2_text = "Reageer en vul aan" />
<#assign tooltip_text = "Status van dit topic - Lees de reacties en vul aan waar nodig." />
<#elseif currentUser != "topicstarter" >
<#assign fase2_text = "Reageer en help mee" />
<#assign tooltip_text = "Status van dit topic - Reageer en help mee. Heb jij het goede antwoord?" />
<#elseif currentUser == "topicstarter" && (nonTSreplies == 0) && withinSLA == true>
<#assign fase2_text = "Wacht op reacties" />
<#assign tooltip_text = "Status van jouw topic - Wacht op reacties van anderen." />
<#elseif currentUser == "topicstarter" && (nonTSreplies == 0) && withinSLA == false>
<#assign fase2_text = "Krijg meer reacties" />
<#assign tooltip_text = "Status van jouw topic - Met deze link krijg je tips voor meer reacties." />
<#assign show_tipLink = true />
<#elseif currentUser == "topicstarter" && (nonTSreplies > 0)>
<#assign fase2_text = "Reageer of markeer oplossing" />
<#assign tooltip_text = "Status van jouw topic - Geef meer details of markeer de beste reactie als oplossing." />
</#if>
</#if>
</#if>
<#recover>
</#attempt>
<#-------------------- DYNAMIC STYLE ---------------->
<#attempt>
<#assign barPosition = "0%" />
<#if page.name == "ForumTopicPage" && topicData?has_content >
<#assign fase1_class = "success" />
<#assign fase2_class = "current" />
<#assign barPosition = "50%" />
<#if topic_has_solution == true >
<#assign fase2_class = "success" />
<#assign fase3_class = "current success" />
<#assign barPosition = "100%" />
<#elseif (nonTSreplies > 0)>
<#assign fase2_class = "current success" />
</#if>
</#if>
<#recover>
</#attempt>
<#-------------------- STYLE ------------------------>
<style>
#topicProgressBar {
margin: 10px 10px 50px 10px;
font-family: "Open Sans",sans-serif;
font-weight: 300;
}
.bar {
height: 6px;
border-radius: 3px;
background-color: #d7dadc;
}
.bar::after {
content: "";
display: block;
width: ${barPosition};
height: 6px;
border-radius: 3px;
background-color: #5daa1a;
}
.overlay {
margin-top: -13px;
position: relative;
}
.fase {
display: inline-block;
position: absolute;
width: fit-content;
}
.step_number {
width: 20px;
height: 20px;
border-radius: 50%;
font-size: 12px;
font-weight: 700;
display: flex;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
flex: 0 0 auto;
transform: translate(-50%, 0)
}
.pos1 {
left: 13%;
}
.pos2 {
left: 50%;
}
.pos3 {
left: 87%;
}
.pos2 a {
color: #000000 !important;
text-decoration: underline !important;
}
.pos3 a {
color: #5daa1a !important;
text-decoration: underline !important;
}
.current .step_number {
background-color: #d7dadc;
border-width: 2px;
border-style: solid;
border-color: #d7dadc;
color: #ffffff;
}
.success .step_number {
background-color: #5daa1a;
border-width: 2px;
border-style: solid;
border-color: #5daa1a;
color: #ffffff;
}
.next .step_number {
background-color: #ffffff;
border-width: 2px;
border-style: solid;
border-color: #d7dadc;
color: #d7dadc;
}
.current .description_nba {
font-weight: 700;
}
.current .description_nba span::before {
content: "\f105 ";
font-family: "FontAwesome";
font-size: 14px;
font-weight: 300;
padding-right: 3px;
}
.pos3 .description_nba span::before {
color: #5daa1a !important;
}
.next .description_nba {
color: #d7dadc;
}
.description_nba {
font-size: 14px;
transform: translate(-50%, 0);
color: #000000;
margin-top: -2px;
}
/* replace step_number 3 for a checkmark icon upon success */
.pos3.success .step_number::before {
font-family: "CustomIcons";
content: "\e90b";
font-size: 10px;
margin-top: 4px;
}
.pos3.success .step_number span {
display: none;
}
/* extra styling for the postpage */
.lia-quilt-post-page #topicProgressBar {
margin: 0 auto !important;
max-width: 1200px !important;
}
.lia-quilt-post-page #topicProgressBar .wrapper {
margin: 25px 15px 30px 15px !important;
}
</style>
<#-------------------- RENDER THE THING -------------->
<#attempt>
<#if page.name == "PostPage" || (coreNode.ancestors[0].shortTitle == "Support" && coreNode.shortTitle != "Archief" && coreNode.shortTitle != "Offtopic") >
<div id="topicProgressBar" title="${tooltip_text}" >
<div class="wrapper">
<div class="bar">
</div>
<div class="overlay">
<div class="fase pos1 ${fase1_class}">
<div class="step_number"><span>1</span></div>
<div class="description_nba"><span>${fase1_text}</span></div>
</div>
<div class="fase pos2 ${fase2_class}">
<div class="step_number"><span>2</span></div>
<div class="description_nba">
<#if show_tipLink == true>
<span><a href="${tipLink}" target="_blank">${fase2_text}</a></span>
<#else>
<span>${fase2_text}</span>
</#if>
</div>
</div>
<div class="fase pos3 ${fase3_class}">
<div class="step_number"><span>3</span></div>
<div class="description_nba">
<#if solutionLink?has_content>
<span><a href="${solutionLink}">${fase3_text}</a></span>
<#else>
<span>${fase3_text}</span>
</#if>
</div>
</div>
</div>
</div>
</div>
</#if>
<#recover>
</#attempt>
<#--------------------------------------------------->