Datasnipper's templates were updated for their login page. Chubb notes and todos.

This commit is contained in:
Norm Rasmussen
2024-01-25 18:28:10 -05:00
parent 8ca1d90345
commit 28036e8fa6
34 changed files with 2851 additions and 0 deletions

View File

@ -0,0 +1,54 @@
{% capture course_path %}
{% route course, id: course.id %}
{% endcapture %}
<div class="np-card course-card">
<div class="np-card-container">
<div class="np-progress-bar-container">
<div style="width: {{ course.progress }}%" class="np-card-progress-bar"></div>
</div>
<div class="course-info-wrapper">
<div class="course-info">
<div class="course-level">{{ course.properties.course_level }}</div>
{% unless course.properties.course_length == 0 %}
<div class="course-length">{{ course.properties.course_length }} minutes</div>
{% endunless %}
</div>
</div>
<img
class="np-card-image"
alt="{{ course.name }}"
src="{{ course.image_url }}">
<div class="np-card-content np-card-content-vertical">
<a class="np-card-content-title" href="{{course_path}}">
{{ course.name }}
</a>
<div class="np-card-content-desc">
{{ course.short_description }}
</div>
<div class="np-card-content-footer">
<div class="instructors-wrapper">
{% for instructor in course.instructors %}
<div class="np-content-instructors-content-item">
<img
src="{{ instructor.avatar_url }}"
class="np-content-instructors-content-image"
alt="{{ instructor.name }}" />
<div class="np-content-instructors-content-description">
<div class="np-content-instructors-content-name">
{{ instructor.name }}
</div>
</div>
</div>
{% endfor %}
</div>
{% if course.has_to_restart? %}
{% include "course_version_outdated_popup", path: course_path %}
{% endif %}
<a class="np-button np-button-wide" href="{{ course_path }}">
{% t shared.view %} course
</a>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,29 @@
<div class="np-card training-event-card">
<div class="np-card-container">
<div class="event-info-wrapper">
<div class="event-info">
<div class="event-date">{{ training_event.sessions.first.day }} {{ training_event.sessions.first.month | date: "%b" }}</div>
<div class="event-time">{{ training_event.sessions.first.starts }}</div>
<div class="hidden-event-info np-hidden">
<span class="event-year">{{ training_event.sessions.first.year }}</span>
<span class="event-timezone">{{ training_event.sessions.first.time_zone }}</span>
</div>
</div>
{% if training_event.sessions.first.registered? %}<div class="session-status-label">Registered <i class="far fa-check np-training-session-icon"></i></div>{% endif %}
</div>
<div class="np-card-content-training-event">
<a class="np-card-content-title" href="{% route training_session, id: training_event.sessions.first.id %}">
{{ training_event.title }}
</a>
<div class="np-card-content-subtitle">
{{ training_event.description | strip_html }}
</div>
</div>
<div class="np-card-content">
<div class="event-instructor">{{ training_event.sessions.first.instructor }}</div>
<a class="np-button np-button-wide" href="{% route training_session, id: training_event.sessions.first.id %}">
{% t shared.view %} event
</a>
</div>
</div>
</div>

View File

@ -0,0 +1,38 @@
<div class="np-card-container">
<div class="np-resource-header np-course-header np-card-padding-large">
{% include "course_header" %}
</div>
<div class="np-divider"></div>
<div class="row np-course-content np-card-padding-dynamic">
<div class="col-xs-12 col-sm-6 col-md-5 np-grid-spacing">
<img
src="{{ course.image_url }}"
class="np-top-image np-top-image-spacing"
alt="{{ course.name }}"
/>
{% include "course_outline" %}
{% if course.categories.any? %}
<div class="np-card-content-divider">
{% include "course_categories" %}
</div>
{% endif %}
{% if course.instructors.any? %}
<div class="np-card-content-divider">
{% include "course_instructors" %}
</div>
{% endif %}
{% if course.events.any? %}
<div class="np-card-content-divider">
{% include "course_events" %}
</div>
{% endif %}
</div>
<div class="col-xs-12 col-sm-6 col-md-7">
<div class="np-top-cta course-main-info">
{% include "course_progress_and_cta" %}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,15 @@
<div class="np-top-vocabulary np-text-title np-text-muted">
{{ current_school.course_vocabulary }}
<i class="far fa-graduation-cap np-button-color np-learning-path-icon np-hidden-mobile">
</i>
</div>
<div class="np-top-title">
<a href="{% route home %}" class="np-back-button" aria-label="{% t shared.go_back %}">
<i class="far fa-arrow-left np-hidden-mobile np-icon-back"></i>
</a>
</div>
<img
src="{{ course.image_url }}"
class="np-top-image np-hidden-desktop"
alt="{{ course.name }}"
/>

View File

@ -0,0 +1,52 @@
<div class="np-top-cta-progress-content">
<div class="course-info-wrapper">
<div class="course-info">
<div class="course-level">{{ course.properties.course_level }}</div>
{% unless course.properties.course_length == 0 %}
<div class="course-length">{{ course.properties.course_length }} minutes</div>
{% endunless %}
</div>
</div>
<div class="np-top-title">
{{ course.name }}
</div>
<div class="np-flex progress-wrapper">
<div class="np-progress-bar-container">
<div style="width: {{ course.progress }}%" class="np-button-background-color np-card-progress-bar"></div>
</div>
<div class="np-top-cta-progress-text">{{course.progress}}%</div>
</div>
</div>
<div class="np-card-text">
{{ course.full_description }}
</div>
{% if course.learner_can_retake? %}
<form action="{% route course_retake, id: course.id %}" method="POST">
{% form_authenticity_token %}
<button type="submit" class="np-top-button np-button-font-color np-button np-button-big">
{% t .retake, key: current_school.course_vocabulary %}
</button>
</form>
{% else %}
<a
class="np-top-button np-button-font-color np-button np-button-big"
{% if course.enrolled? %}
href="{% route course_viewer, course_id: course.id, learning_path_id: params.learning_path_id %}"
{% else %}
href="{% route course_enrollment, code: course.enrollment_code %}"
{% endif %}
>
{% if course.enrolled? == false %}
{% t shared.enroll %}
{% elsif course.started? == false %}
{% t shared.course.start, key: current_school.course_vocabulary %}
{% elsif course.completed? %}
{% t shared.course.view, key: current_school.course_vocabulary %}
{% else %}
{% t shared.continue %}
{% endif %}
</a>
{% endif %}

View File

@ -0,0 +1,15 @@
{% if courses.in_catalog.any? %}
<div class="np-catalog-courses row row-with-thumbnails">
{% for course in courses.in_catalog %}
<div class="col-xs-12 col-md-6 col-lg-4 np-stretch-content">
{% include "cards_course" with course %}
</div>
{% endfor %}
</div>
{% else %}
{% capture message %}
{% t shared.zero_state.courses.catalog
, key: current_school.course_vocabulary %}
{% endcapture %}
{% include "courses_zero_state", message: message %}
{% endif %}

View File

@ -0,0 +1,20 @@
{% if courses.enrolled.any? %}
<div class="row row-with-thumbnails">
{% for course in courses.enrolled %}
{% assign course_categories = "" %}
{% for cat in course.categories %}
{% assign cat_name = cat.name | replace: " ", "-" | downcase %}
{% assign course_categories = course_categories | append: cat_name %}
{% endfor %}
<div class="{{ class }} course-columns" data-categories='{{course_categories}}'>
{% include "cards_course" with course %}
</div>
{% endfor %}
</div>
{% else %}
{% capture message %}
{% t shared.zero_state.courses.index
, key: current_school.course_vocabulary %}
{% endcapture %}
{% include "courses_zero_state", message: message %}
{% endif %}

View File

@ -0,0 +1,133 @@
{% assign enrolled_categories = categories.enrolled %}
<div class="filter-sidebar">
<div class="filter-group">
<div class="filter-group-heading">What are you looking for?</div>
<div class="filters">
{% for category in enrolled_categories %}
<div class="filter-item">
<label class="filter">
{{ category.name }}
<input
type="checkbox"
name="{{category.name}}"
value="{{category.name}}" />
<span class="checkmark"></span>
</label>
</div>
{% endfor %}
</div>
</div>
<div class="filter-group">
<div class="filter-group-heading">What is your learning style?</div>
<div class="filters"></div>
</div>
<div class="filters-reset np-button" onClick="resetFilters()">Reset all Filters</div>
</div>
<style>
.filter-sidebar {
color: #fff;
padding-left: 32px;
}
.filter-group {
margin-bottom: 50px;
}
.filter-group-heading {
font-size: 20px;
font-weight: 500;
line-height: 36px;
margin-bottom: 16px;
}
.filter-item label {
color: #E6E8EB;
font-size: 18px;
font-weight: 500;
line-height: 32px;
display: block;
position: relative;
padding-left: 35px;
margin-bottom: 12px;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.filter-item input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.filter-item .checkmark {
position: absolute;
top: 3px;
left: 0;
height: 24px;
width: 24px;
background-color: transparent;
border: 1px solid #fff;
border-radius: 4px;
}
.filter-item .checkmark:after {
content: "";
position: absolute;
display: none;
}
input:checked ~ .checkmark:after {
display: block;
}
.filter-item .checkmark:after {
left: 8px;
top: 3px;
width: 5px;
height: 10px;
border-style: solid;
border-color: #fff;
border-width: 0 2px 2px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.filters-reset {
font-size: 20px;
font-weight: 600;
line-height: 24px;
border: 1px solid #fff;
cursor: pointer;
padding: 16px 24px;
border-radius: 8px;
color: #fff;
background-color: transparent;
width: 100%;
height: auto;
}
</style>
<script>
window.addEventListener("DOMContentLoaded", function() {})
function resetFilters() {
console.log("resettting filtes")
const allFilters = document.querySelectorAll("input[type='checkbox']")
allFilters.forEach(element => {
element.checked = false;
});
const allCourses = document.querySelectorAll('.course-columns');
allCourses.forEach(element => {
element.style.display = 'flex';
});
}
</script>

View File

@ -0,0 +1,289 @@
<footer class="np-footer">
<div class="np-footer-top np-max-width">
{% if website_footer.show_navigation_links? %}
<div class="np-footer-navigation">
<div class="footer-navigation-links-group">
<div class="footer-navigation-links-heading">Product</div>
<div class="footer-navgiation-links-list">
<a
href="https://www.datasnipper.com/product/platform"
class="footer-navigation-link"
target="_blank">Platform</a>
<a
href="https://www.datasnipper.com/product/financial-statement-suite"
class="footer-navigation-link"
target="_blank">Financial Statement Suite</a>
</div>
</div>
<div class="footer-navigation-links-group">
<div class="footer-navigation-links-heading">Resources</div>
<div class="footer-navgiation-links-list">
<a
href="https://knowledge.datasnipper.com/"
class="footer-navigation-link"
target="_blank">Knowledge Base</a>
<a
href="https://www.datasnipper.com/resources?type=Blog"
class="footer-navigation-link"
target="_blank">Blogs</a>
<a
href="https://www.datasnipper.com/customers"
class="footer-navigation-link"
target="_blank">Customer Stories</a>
</div>
</div>
<div class="footer-navigation-links-group">
<div class="footer-navigation-links-heading">Company</div>
<div class="footer-navgiation-links-list">
<a
href="https://www.datasnipper.com/about-us"
class="footer-navigation-link"
target="_blank">About us</a>
<a
href="https://careers.datasnipper.com/"
class="footer-navigation-link"
target="_blank">Careers</a>
<a
href="https://www.datasnipper.com/privacy-policy"
class="footer-navigation-link"
target="_blank">Privacy Policy</a>
</div>
</div>
</div>
{% endif %}
<div>
<nav class="np-footer-social-links">
{% if website_footer.show_social_media_links? %}
<ul class="np-footer-social-links-list">
{% for social_media_link in website_footer.social_media_links %}
{% unless social_media_link.name == "twitter" %}
<li class="np-footer-social-links-item">
<a
class="np-footer-social-links-link np-button-font-color"
href="{{ social_media_link.link }}"
target="_blank"
title="{{ social_media_link.name }}">
{% if social_media_link.name == "linkedin" %}
<i class="np-footer-social-links-icon np-button-font-color
fab fa-linkedin-in">
</i>
{% else %}
<i class="np-footer-social-links-icon np-button-font-color
fab fa-{{ social_media_link.name }}">
</i>
{% endif %}
</a>
</li>
{% endunless %}
{% endfor %}
{% for social_media_link in website_footer.social_media_links %}
{% if social_media_link.name == "twitter" %}
<li class="np-footer-social-links-item">
<a
class="np-footer-social-links-link np-button-font-color"
href="{{ social_media_link.link }}"
target="_blank"
title="{{ social_media_link.name }}">
<svg
width="1200"
height="1227"
viewBox="0 0 1200 1227"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style="max-height:18px;position: relative;top: 3px;max-width:100%;">
<path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" fill="white" />
</svg>
</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
</nav>
{% if current_school.logo_url %}
<h2 class="np-footer-logo">
<a href="https://www.datasnipper.com/resources/datasnipper-partners-1-percent-for-the-planet" target="_blank">
<img
alt="{{ current_school.name }}"
class="np-footer-logo-image"
src="https://s3.amazonaws.com/static.northpass.com/datasnipper/for-the-planet-logo.png" />
</a>
<a href="https://www.aicpa-cima.com/resources/landing/system-and-organization-controls-soc-suite-of-services" target="_blank">
<img
alt="{{ current_school.name }}"
class="np-footer-logo-image"
src="https://s3.amazonaws.com/static.northpass.com/datasnipper/soc-badge.png" />
</a>
</h2>
{% else %}
<div class="np-school-name np-header-font-color">
{{ current_school.name }}
</div>
{% endif %}
</div>
</div>
<div class="np-footer-bottom np-max-width">
<div class="copyright-notice">©<span id="copyrightYear"></span>
DataSnipper. All rights reserved.</div>
{% if website_footer.show_customer_service_email? and website_footer.school_customer_service_email
%}
<div class="np-footer-support">
<div class="np-footer-support-item np-footer-support-help">
{% t.need_help %}
</div>
<div class="np-footer-support-item np-footer-support-email">
{% t.email %}
</div>
<a class="np-footer-support-item np-footer-support-link np-button-color" href="mailto:{{ website_footer.school_customer_service_email }}">
{{ website_footer.school_customer_service_email }}
</a>
</div>
{% endif %}
</div>
</footer>
<script>
window.addEventListener("DOMContentLoaded", function() {
const year = new Date().getFullYear()
document.getElementById("copyrightYear").innerText = year
})
</script>
<style>
.np-footer {
background-color: #011638;
padding: 44px 16px;
max-width: 1200px;
margin: auto;
}
.np-footer-social-links-list {
justify-content: center;
}
.np-footer-social-links-item {
width: 48px;
height: 48px;
border: 1px solid rgba(255, 255, 255, 0.6);
border-radius: 50%;
margin: 0 12px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
padding: 0;
}
.np-footer-social-links-link {
font-size: 20px;
line-height: 48px;
}
.np-footer-logo {
text-align: center;
margin-bottom: 16px;
}
.np-footer-logo > a {
margin: 0 6px;
text-decoration: none;
}
.np-footer-logo-image {
opacity: 1;
filter: contrast(1);
height: auto;
max-width: 190px;
}
.footer-navigation-links-group {
margin-bottom: 20px;
text-align: center;
}
.footer-navigation-links-heading {
color: #fff;
font-size: 20px;
font-style: normal;
font-weight: 600;
margin-bottom: 12px;
}
.footer-navigation-link {
display: block;
color: rgba(255, 255, 255, 0.6);
margin-bottom: 8px;
}
.np-footer-bottom {
border-top: 1px solid rgba(255, 255, 255, 0.2);
padding-top: 32px;
}
.copyright-notice {
color: rgba(255, 255, 255, 0.6);
font-size: 14px;
line-height: 24px;
display: block;
margin: auto;
}
@media (min-width: 768px) {
.np-footer {
padding: 100px 16px;
}
.np-footer-navigation {
display: flex;
}
.footer-navigation-links-group {
margin-right: 32px;
text-align: left;
}
.np-footer-social-links-list {
padding-left: 0;
margin-bottom: 20px;
margin-top: 0;
}
.footer-navigation-link {
margin-bottom: 12px;
}
.np-footer-logo {
margin-right: 0;
}
}
@media (min-width: 1200px) {
.footer-navigation-links-group {
margin-right: 80px;
}
}
</style>
<script>
const isInIframe = inIframe()
if (isInIframe) {
document.querySelector(".np-header").style.display = "none";
document.querySelector(".np-footer").style.display = "none";
} else {
console.log("not iframed")
}
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
</script>

View File

@ -0,0 +1,40 @@
<script>
function updateEventTimezone() {
document.querySelectorAll(".training-event-card .event-info").forEach((cardDetails) => {
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const day = cardDetails.querySelector(".event-date").innerText.split(" ")[0]
const month = cardDetails.querySelector(".event-date").innerText.split(" ")[1]
const year = cardDetails.querySelector(".event-year").innerText
const startTime = cardDetails.querySelector(".event-time").innerText;
var eventShortTimezone = cardDetails.querySelector(".event-timezone").innerText
if (eventShortTimezone == "CET") {
eventShortTimezone = "GMT+0100"
} else if (eventShortTimezone == "CEST") {
eventShortTimezone = "GMT+0200"
}
var startDate = new Date(`${day} ${month} ${year} ${startTime} ${eventShortTimezone}`);
var userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
var userTimeZoneAbbreviation = new Date().toLocaleTimeString('en-us',{timeZone: userTimeZone, timeZoneName:'short'}).split(' ')[2];
var startFormatedTime = formatAMPM(startDate)
cardDetails.querySelector(".event-time").innerText = startFormatedTime
cardDetails.querySelector(".event-date").innerText = `${startDate.getDate()} ${monthNames[startDate.getMonth()]}`
})
function formatAMPM(date) {
var hours = date.getHours();
var minutes = date.getMinutes();
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes < 10 ? '0'+minutes : minutes;
var strTime = hours + ':' + minutes + ' ' + ampm;
return strTime;
}
}
</script>

View File

@ -0,0 +1,146 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.9.4/tiny-slider.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.9.2/min/tiny-slider.js"></script>
<script>
function createCarousel(customOptions = {}) {
const defaultOptions = {
animateDelay: false,
animateIn: 'tns-fadeIn',
animateNormal: 'tns-normal',
animateOut: 'tns-fadeOut',
arrowKeys: false,
autoHeight: false,
autoplay: false,
autoplayButton: false,
autoplayButtonOutput: true,
autoplayDirection: 'forward',
autoplayHoverPause: false,
autoplayPosition: 'top',
autoplayResetOnVisibility: true,
autoplayText: [
'start', 'stop'
],
autoplayTimeout: 5000,
autoWidth: false,
axis: 'horizontal',
center: false,
container: '.slider',
controls: true,
controlsContainer: false,
controlsPosition: 'top',
controlsText: [
'<span class="fas fa-chevron-left"></span>', '<span class="fas fa-chevron-right"></span>'
],
edgePadding: 0,
fixedWidth: false,
freezable: true,
gutter: 0,
items: 1,
lazyload: false,
lazyloadSelector: '.tns-lazy-img',
loop: true,
mode: 'carousel',
mouseDrag: false,
nav: false,
navAsThumbnails: false,
navContainer: false,
navPosition: 'top',
nested: false,
nextButton: false,
nonce: false,
onInit: false,
prevButton: false,
preventActionWhenRunning: false,
preventScrollOnTouch: false,
responsive: {
500: {
items: 2
},
992: {
items: 3
},
1200: {
items: 4
}
},
rewind: false,
slideBy: 1,
speed: 300,
swipeAngle: 15,
touch: true,
useLocalStorage: true,
viewportMax: false
};
tns({
... defaultOptions,
...customOptions
})
}
</script>
<style>
.tns-slider {
display: flex;
}
.tns-item {
margin-bottom: 10px;
}
.tns-outer {
position: relative;
}
div[aria-label='Carousel Navigation'] {
position: relative;
display: flex;
justify-content: flex-end;
}
[data-controls] {
border: 0;
padding: 0;
z-index: 1;
cursor: pointer;
background-color: #0D21A1;
border: 1px solid #fff;
color: #fff;
border-radius: 50%;
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
line-height: normal;
margin-top: 16px;
}
[data-controls="prev"] {}
[data-controls="next"] {
margin-left: 16px;
}
[data-controls="prev"],
[data-controls="next"] {}
.tns-nav {
text-align:center;
margin-top: -8px;
}
.tns-nav button {
border-radius: 50%;
padding: 6px;
margin: 0 5px;
background-color: #E6E8EB;
border: none;
}
.tns-nav button.tns-nav-active {
background-color:#0D21A1;
}
</style>

View File

@ -0,0 +1,15 @@
{% styles default %}
{% styles colors %}
{% styles custom %}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Jost:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js" type="text/javascript"></script>
{% include 'generic_tns_carousel' %}
{% include 'function_update_event_timezone' %}

View File

@ -0,0 +1,258 @@
<script>
const defaultPageTitle = document.title
if (window.location.pathname == "/app/dashboard") {
document.title = `${defaultPageTitle} | My Courses `
} else if (window.location.pathname == "/app/learning_paths") {
document.title = `${defaultPageTitle} | Learning Paths`
} else if (window.location.pathname == "/app/training_events") {
document.title = `${defaultPageTitle} | Training Events`
} else if (window.location.pathname == "/app/upcoming-trainings") {
document.title = `${defaultPageTitle} | Upcoming Trainings`
}
</script>
<header class="np-header np-header-color">
<div class="np-header-content np-max-width">
<div class="np-hidden-desktop np-header-mobile-menu-nav">
{% if current_person.signed_in? %}
<button
data-toggle-class="np-hidden"
class="np-header-mobile-menu-nav-button fal fa-times np-hidden np-header-font-color"
data-toggle-target=".np-header-mobile-avatar-menu,.np-header-mobile-menu-content, .np-main, .np-footer"></button>
<button
data-test="open-mobile-menu"
data-toggle-class="np-hidden"
class="np-header-mobile-menu-nav-button np-header-mobile-avatar-menu"
data-toggle-target=".fa-times, .np-header-mobile-menu-content, .np-main, .np-footer">
<img
alt="{{ current_person.name }}"
class="np-header-avatar-image"
src="{{ current_person.avatar_url }}" />
</button>
{% endif %}
</div>
{% if current_school.logo_url %}
<h1 class="np-header-logo">
<a href="{% route home %}">
<img
alt="{{ current_school.name }}"
class="np-header-logo-image"
src="{{ current_school.logo_url }}" />
</a>
</h1>
{% else %}
<a href="{% route home %}" class="np-school-name np-header-font-color">
{{ current_school.name }}
</a>
{% endif %}
<div class="np-hidden-mobile np-header-desktop-nav">
<ul class="np-header-desktop-nav-list">
{% for link in navigations.sub_navigation %}
{% unless link.label == "Catalog" %}
{% assign link_url = "" %}
{% comment %} {% if link.label == "Dashboard" %}
{% assign link_url = "/app/courses" %}
{% else %}
{% assign link_url = link.url %}
{% endif %} {% endcomment %}
<li class="np-header-desktop-nav-item">
<a href="{{ link.url }}" class="np-header-desktop-nav-link {% if link.label == "Events" %}np-button{% else %}np-header-font-color{% endif %} {% if link.label == "Catalog" %}link-dropdown{% endif %}">
{% if link.label == "Courses" or link.label == "Dashboard" %}
My Courses
{% elsif link.label == "Catalog" %}
Catalog
<i
data-test="open-catalog-dropdown"
data-toggle-class="np-hidden"
data-toggle-target=".np-catalog-dropdown-content"
class="far fa-chevron-down"></i>
{% elsif link.label == "Events" %}
Live events
{% else %}
{{ link.label }}
{% endif %}
</a>
{% comment %} {% if link.label == "Catalog" %}
<div class="np-catalog-dropdown-content np-hidden">
<form
class="np-header-search"
data-test="mobile-search"
method="get"
action="{% route search %}">
<svg
xmlns="http://www.w3.org/2000/svg"
width="21"
height="20"
viewBox="0 0 21 20"
fill="none">
<path
d="M18 17.5L15.0834 14.5833M17.1667 9.58333C17.1667 13.4954 13.9954 16.6667 10.0833 16.6667C6.17132 16.6667 3 13.4954 3 9.58333C3 5.67132 6.17132 2.5 10.0833 2.5C13.9954 2.5 17.1667 5.67132 17.1667 9.58333Z"
stroke="#011638"
stroke-width="1.66667"
stroke-linecap="round"
stroke-linejoin="round" />
</svg>
<input
aria-label="{% t .search %}"
class="np-dropdown-search-input"
type="text"
name="q"
placeholder="{% t .search %}" />
</form>
{% for filter in courses.filters limit: 3 %}
<a href="/app/catalog?filter[category_uuid][in][]={{filter.value}}" class="dropdown-category-link">{{ filter.name }}</a>
{% endfor %}
</div>
{% endif %} {% endcomment %}
</li>
{% endunless %}
{% endfor %}
{% for website_navigation in navigations.header_navigations_external %}
<li class="np-header-desktop-nav-item">
<a
href="{{ website_navigation.path }}"
class="np-header-desktop-nav-link np-header-font-color"
target="_blank">
{{ website_navigation.name }}
</a>
</li>
{% endfor %}
</ul>
</div>
{% if current_person.signed_in? %}
{% else %}
<a
class="np-header-sign-in np-header-desktop-nav-link np-header-font-color"
aria-label="{% t shared.sign_in %}"
href="{% route login %}">
{% t shared.sign_in %}
</div>
{% endif %}
</div>
</header>
<div class="np-hidden-desktop">
<div class="np-header-mobile-menu-content np-hidden">
{% if current_person.signed_in? %}
<img
alt="{{ current_person.name }}"
class="np-header-mobile-menu-content-avatar"
src="{{ current_person.avatar_url }}" />
<div class="np-header-mobile-menu-content-name">
{{ current_person.name }}
</div>
{% endif %}
<div class="np-header-mobile-menu-content-nav">
<form
class="np-header-search"
data-test="mobile-search"
method="get"
action="{% route search %}">
<input
aria-label="{% t .search %}"
class="np-header-search-input"
type="text"
name="q"
placeholder="{% t .search %}" />
<i class="np-header-search-icon far fa-search"></i>
</form>
{% for website_navigation in navigations.header_navigations %}
<a
href="{{ website_navigation.path }}"
class="np-header-mobile-menu-content-button"
{% if website_navigation.external? %}
target="_blank"
{% endif %}>
{{ website_navigation.name }}
</a>
{% endfor %}
<div class="np-header-mobile-menu-content-line"></div>
{% unless current_school.sso_active? %}
<a class="np-header-mobile-menu-content-button" href="{% route account %}">
{% t.profile_settings %}
</a>
{% endunless %}
<a class="np-header-mobile-menu-content-button np-danger" href="{% route logout %}">
{% t.sign_out %}
</a>
</div>
</div>
</div>
{% include "messages" %}
<style>
.np-header-desktop-nav-list {
align-items: center;
}
.np-header-desktop-nav-item {
position: relative;
}
.np-header-desktop-nav-item .np-header-desktop-nav-link {
font-size: 18px;
font-weight: 600;
line-height: 24px;
letter-spacing: -0.18px;
position: relative;
}
.np-header-desktop-nav-link.np-button {
display: inline-flex;
color: #fff;
}
.np-header-desktop-nav-link.link-dropdown i.np-hidden {
display: inline-block !important;
transform: rotate(180deg);
}
.np-catalog-dropdown-content {
position: absolute;
top: 78px;
background-color: #011638;
z-index: 50;
padding: 24px;
width: 209px;
right: 0;
border-radius: 8px;
color: #fff;
font-weight: 600;
}
.np-dropdown-search-input {
padding: 10px 14px 10px 34px;
border-radius: 8px;
width: 100%;
border: none;
}
.dropdown-category-link {
color: #E7E9F5;
text-decoration: none;
display: block;
margin: 14px 0 6px;
font-weight: 600;
}
.np-header-search svg {
position: absolute;
top: 8px;
left: 8px;
}
@media screen and (min-width: 768px) {
.np-header {
height: 100px;
padding-left: 0;
padding-right: 0;
}
}
</style>

View File

@ -0,0 +1,47 @@
<div class="my-courses-carousel">
{% for course in courses.enrolled %}
<div class="course-slide">
{% include "cards_course" with course %}
</div>
{% endfor %}
</div>
<div class="courses-carousel-controls carousel-controls">
<div class="carousel-arrow far fa-chevron-left"></div>
<div class="carousel-arrow far fa-chevron-right"></div>
</div>
<style>
.course-slide .np-card {
padding: 0 8px;
}
</style>
<script>
var slider = tns({
container: '.my-courses-carousel',
items: 1,
controlsContainer: document.querySelector(".courses-carousel-controls"),
mouseDrag: true,
autoplay:false,
controls:true,
gutter:16,
navPosition:'bottom',
loop: true,
nav: false,
responsive: {
640: {
items: 2
},
900: {
items: 3
},
1200: {
items: 4,
}
}
});
</script>

View File

@ -0,0 +1,76 @@
<div class="section-my-courses">
<div class="np-max-width">
<div class="row" style="margin-bottom:32px;">
<div class="col-xs-12 col-md-8">
<div class="my-courses-title">
My Courses
</div>
</div>
<div class="col-xs-12 col-md-4 np-hidden-mobile">
<div class="my-courses-view-all">
<a href="/app/courses" class="np-button np-button-white">View all courses</a>
</div>
</div>
</div>
<div class="row">
{% if courses.enrolled.any? %}
{% assign enrolled_courses = courses.enrolled | sort: "progress" %}
{% for course in enrolled_courses limit: 4 %}
<div class="col-xs-12 col-sm-4 col-md-3">
{% include "cards_course" with course %}
</div>
{% endfor %}
{% else %}
<div class="col-xs-12">
{% capture message %}
{% t shared.zero_state.courses.index
, key: current_school.course_vocabulary %}
{% endcapture %}
{% include "courses_zero_state", message: message %}
</div>
{% endif %}
</div>
<div class="row" style="margin-top:32px;">
<div class="col-xs-12 col-md-4 np-hidden-desktop">
<div class="upcoming-events-view-all">
<a href="/app/dashboard" class="np-button np-button-white">View all courses</a>
</div>
</div>
</div>
</div>
</div>
<style>
.section-my-courses {
padding: 0 16px 64px;
}
.my-courses-title {
color: #fff;
font-size: 32px;
font-weight: 600;
line-height: 38px;
letter-spacing: -0.4px;
}
.my-courses-view-all {
text-align: center;
}
@media(min-width:768px) {
.my-courses-title {
font-size: 40px;
line-height: 46px;
}
.my-courses-view-all {
text-align: right;
}
.section-my-courses .np-card.course-card {
padding: 0 4px;
}
}
</style>

View File

@ -0,0 +1,99 @@
{% assign events_to_hide = "Introduction to DataSnipper, Introduction to the Financial Statement Suite, Automation with DataSnipper, Welcome to the Financial Statement Suite, DataSnipper Tips & Tricks, DataSnipper Q&A, Financial Statement Suite Tips & Tricks" | split: ", " %}
<div class="section-upcoming-events">
<div class="np-max-width">
<div class="row">
<div class="col-xs-12 col-md-8">
<div class="upcoming-events-title">
Upcoming Events
</div>
</div>
<div class="col-xs-12 col-md-4 np-hidden-mobile">
<div class="upcoming-events-view-all">
<a href="/app/training_events" class="np-button np-button-white">View all live events</a>
</div>
</div>
</div>
<div class="row events-carousel-row">
<div class="col-xs-12">
<div class="upcoming-events-carousel">
{% if training_events.available.any? %}
{% assign training_events_count = 0 %}
{% for training_event in training_events.available %}
{% unless events_to_hide contains training_event.title %}
<div class="event-item">
{% include "cards_training_event" with training_event %}
</div>
{% assign training_events_count = training_events_count | plus: 1 %}
{% endunless %}
{% if training_events_count > 3 %}
{% break %}
{% endif %}
{% endfor %}
{% else %}
{% include "training_events_zero_state" %}
{% endif %}
</div>
<div class="events-carousel-nav">
<div class="prev-button far fa-arrow-left"></div>
<div class="next-button far fa-arrow-right"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-4 np-hidden-desktop">
<div class="upcoming-events-view-all">
<a href="/app/training_events" class="np-button np-button-white">View all live events</a>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", (event) => {
const eventsCarouselOptions = {
container: '.upcoming-events-carousel',
controlsContainer: ".events-carousel-nav"
}
createCarousel(eventsCarouselOptions)
updateEventTimezone()
});
</script>
<style>
.section-upcoming-events {
padding: 0 16px 64px;
}
.upcoming-events-title {
color: #fff;
font-size: 32px;
font-weight: 600;
line-height: 38px;
letter-spacing: -0.4px;
}
.upcoming-events-view-all {
text-align: center;
}
.events-carousel-row {
margin-top: 40px;
}
@media(min-width: 768px) {
.upcoming-events-title {
font-size: 40px;
line-height: 46px;
}
.upcoming-events-view-all {
text-align: right;
}
}
</style>

View File

@ -0,0 +1,48 @@
<div class="homepage-welcome">
<div class="np-max-width">
<div class="row">
<div class="col-xs-12">
<div class="welcome-title">Welcome back, {{ current_person.first_name }}</div>
<div class="welcome-subtitle">{{ homepage.subheadline }}</div>
</div>
</div>
{% include "homepage_widgets" %}
</div>
</div>
<style>
.homepage-welcome {
margin: 0 16px 64px;
background-color: #E7E9F5;
padding: 64px 16px;
border-radius: 0 0 12px 12px;
}
.homepage-welcome .welcome-title {
color: #0C176C;
font-size: 48px;
font-weight: 600;
line-height: 56px;
letter-spacing: -0.48px;
margin-bottom: 12px;
}
.homepage-welcome .welcome-subtitle {
color: #0C176C;
font-size: 20px;
font-style: normal;
font-weight: 400;
line-height: 30px;
opacity: 0.8;
}
@media(min-width:768px) {
.homepage-welcome {
margin: 0 16px 100px;
padding: 88px 16px;
}
}
</style>

View File

@ -0,0 +1,150 @@
{% assign count_complete = 0 %}
{% assign count_in_progress = 0 %}
{% assign percent_in_progress = 0 %}
{% assign percent_completed = 0 %}
{% assign total_enrolled_courses = 0 %}
{% if courses.enrolled.any? %}
{% assign total_enrolled_courses = courses.enrolled | size | times: 1 %}
{% for course in courses.enrolled %}
{% if course.completed? %}
{% assign count_complete = count_complete | plus: 1 %}
{% elsif course.started? %}
{% assign count_in_progress = count_in_progress | plus: 1 %}
{% endif %}
{% endfor %}
{% assign percent_in_progress = count_in_progress | times: 100 | divided_by: total_enrolled_courses %}
{% assign percent_completed = count_complete | times: 100 | divided_by: total_enrolled_courses %}
{% endif %}
<div class="widgets-section">
<div class="row np-flex-center">
<div class="col-xs-12 col-sm-6 col-md-4">
<div class="info-widget">
<div class="widget-label">Courses in progress</div>
<div class="widget-progress-bar">
<div class="progress" style="width:{{percent_in_progress}}%"></div>
</div>
<div class="widget-number">
<span>{{ count_in_progress }}</span>/{{ total_enrolled_courses }}</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4">
<div class="info-widget">
<div class="widget-label">Courses completed</div>
<div class="widget-progress-bar">
<div class="progress" style="width:{{percent_completed}}%"></div>
</div>
<div class="widget-number">
<span>{{ count_complete }}</span>/{{ total_enrolled_courses }}</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4">
<div class="info-widget">
<div class="widget-label">Your Badges</div>
<div class="badges badges-carousel">
{% for course in courses.enrolled %}
{% if course.properties.course_badge contains "http" %}
<div class="badge {% if course.completed? %}badge-completed{% endif %}">
<img src="https://s3.amazonaws.com/static.northpass.com/datasnipper/badge-explorer.png" />
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<style>
.widgets-section {
margin-top: 64px;
}
.info-widget {
border-radius: 12px;
border: 1px solid #EAECF0;
background: #fff;
box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.06), 0 1px 3px 0 rgba(16, 24, 40, 0.10);
padding: 24px;
margin-bottom: 16px;
height: calc(100% - 16px);
}
.widget-label {
font-size: 20px;
font-style: normal;
font-weight: 500;
line-height: 24px;
}
.widget-progress-bar {
margin: 24px 0;
border-radius: 8px;
background: #E6E8EB;
height: 12px;
}
.widget-progress-bar .progress {
background-color: #0D21A1;
border-radius: 8px;
height: 12px;
min-width: 12px;
}
.info-widget .widget-number {
font-size: 20px;
font-weight: 600;
line-height: 38px;
color: #5964B7;
}
.info-widget .widget-number > span {
font-size: 40px;
color: #0D21A1;
}
.info-widget .badges {
display: flex;
margin-top: 16px;
}
.info-widget .badge,
.info-widget .badge img {
max-width: 100px;
}
.info-widget .badge:not(.badge-completed) img {
filter:grayscale(1);
opacity: 0.4;
}
@media(min-width:768px) {}
</style>
<script>
document.addEventListener("DOMContentLoaded", (event) => {
const badgesCarouselOptions = {
container: '.badges-carousel',
items: 3,
mouseDrag: true,
nav:true,
navPosition: 'bottom',
controls:false,
slideBy: 3,
loop:false,
responsive: {
1200: {
items: 4,
slideBy: 4,
}
},
}
createCarousel(badgesCarouselOptions)
});
</script>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,17 @@
{% assign events_to_hide = "Introduction to DataSnipper, Introduction to the Financial Statement Suite, Automation with DataSnipper, Welcome to the Financial Statement Suite, DataSnipper Tips & Tricks, DataSnipper Q&A, Financial Statement Suite Tips & Tricks" | split: ", " %}
<div class="np-dashboard-resources">
{% if training_events.available.any? %}
<div class="row row-with-thumbnails">
{% for training_event in training_events.available %}
{% unless events_to_hide contains training_event.title %}
<div class="col-xs-12 col-sm-6 col-lg-4 np-stretch-content">
{% include "cards_training_event" with training_event %}
</div>
{% endunless %}
{% endfor %}
</div>
{% else %}
{% include "training_events_zero_state" %}
{% endif %}
</div>

View File

@ -0,0 +1,49 @@
{% if training_session.approved? or training_session.pending? %}
<div class="np-training-session-cta-note">
<i class="far fa-check np-training-session-icon"></i>
{% t .registered %}
</div>
{% elsif training_session.denied? %}
<div class="np-training-session-cta-note np-training-session-cta-note-error">
{% t .denied %}
</div>
{% elsif training_session.too_late? %}
<div class="np-training-session-cta-note np-training-session-cta-note-error">
{% t .too_late %}
</div>
{% elsif training_session.no_seats? %}
<div class="np-training-session-cta-note np-training-session-cta-note-error">
{% t .no_seats %}
</div>
{% endif %}
<div class="np-training-session-cta">
<div class="np-training-session-cta-buttons">
<form
action="{% route training_session_registration, id: training_session.id %}"
method="post"
>
{% form_authenticity_token %}
{% if training_session.internal? and training_session.approved? %}
{% if features.training_events_google_calendar? %}
{% include "training_session_calendars" %}
<button type="submit" class="np-top-button np-button np-button-big np-button-secondary">
{% t .unregister %}
</button>
{% else %}
<button type="submit" class="np-top-button np-button-font-color np-button np-button-big">
{% t .unregister %}
</button>
{% endif %}
<input type="hidden" name="_method" value="delete" />
{% endif %}
{% if training_session.not_registered? %}
<button type="submit" class="np-top-button np-button np-button-big">
{% t .register %}
</button>
{% endif %}
</form>
</div>
</div>

View File

@ -0,0 +1,24 @@
<div class="np-card-spacing-large">
{% include "training_session_date" %}
<div class="np-training-session-time">
<i class="fal fa-clock np-button-color np-training-session-icon"></i>
<span>{{ training_session.time_period }}</span> <span>{{ training_session.time_zone }}</span>
</div>
{% if training_session.location %}
<div class="np-training-session-location">
<i class="fal fa-map-marker-alt np-button-color np-training-session-icon"></i>
{{ training_session.location }}
</div>
{% endif %}
{% if training_session.session_url %}
<div class="np-training-session-location">
<i class="fal fa-map-marker-alt np-button-color np-training-session-icon"></i>
<a href="{{ training_session.session_url }}" class="np-button-color" target="_blank" >
{{ training_session.session_url }}
</a>
</div>
{% endif %}
</div>

View File

@ -0,0 +1,29 @@
<div class="np-top-vocabulary np-text-title">
{% t shared.event_types
, key: training_event.event_type %}
<i class="fal fa-users-class np-button-color np-training-session-icon"></i>
</div>
<div class="np-top-title">
<a
onclick="goBack()"
class="np-back-button"
aria-label="{% t shared.go_back %}">
<i class="far fa-arrow-left np-hidden-mobile np-icon-back"></i>
</a>
{{ training_event.title }}
</div>
<script>
function goBack() {
const fallbackUrl = '/app/training_events';
var prevPage = window.location.href;
window.history.go(-1);
setTimeout(function() {
if (window.location.href == prevPage) {
window.location.href = fallbackUrl;
}
}, 800);
}
</script>

View File

@ -0,0 +1,91 @@
<main class="np-box-container np-open-access">
<div class="np-box">
{% include "header_minimal" %}
<div class="np-box-content-container">
<form class="np-form np-box-content" action="{{ form.url }}" method="get" novalidate>
{% form_authenticity_token %}
<div class="np-form-headline">
{% t shared.welcome_to_school, school_name: current_school.name %}
</div>
<div class="np-form-subheadline">
{% t .headline, key: current_school.course_vocabulary %}
</div>
<div class="np-form-field">
<label class="np-input-label" for="learner_first_name">
{% t shared.first_name %}
</label>
<input
class="np-input"
autofocus="autofocus"
type="text"
name="first_name"
id="learner_first_name"
value="{{ form.first_name }}"
/>
</div>
<div class="np-form-field">
<label class="np-input-label" for="learner_last_name">
{% t shared.last_name %}
</label>
<input
class="np-input"
type="text"
name="last_name"
id="learner_last_name"
value="{{ form.last_name }}"
/>
</div>
<div class="np-form-field">
<label class="np-input-label" for="learner_email">
Company Email
</label>
<input
class="np-input"
type="text"
name="email"
id="learner_email"
value="{{ form.email }}"
/>
</div>
<p style="display: none;" id="bad_email_alert">Please enter a valid email address.</p>
<input
type="submit"
name="commit"
value="{% t shared.enter %}"
id="submit_button"
class="np-button np-button-big np-form-action"
/>
</form>
</div>
</div>
</main>
<script>
function checkIfInputsExist (){
window.setTimeout(function(){
// Regular expression to check if string is email
const regexExp = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
// Grabs Email Address Value
const learnerEmail = $("#learner_email")[0].value;
if ($("#learner_email")[0].value.length > 0){
if(regexExp.test(learnerEmail) == false){
console.log("The regex text is: "+regexExp.test(learnerEmail))
$("#learner_email").css("background", "salmon");
$("#bad_email_alert").css("color", "salmon");
$("#bad_email_alert").css("display", "block");
$("#submit_button").css("pointer-events","none");
$("#submit_button").css("background","#c9c9c9");
$("#submit_button").css("color","#0d21a1");
} else {
console.log("The regex text is: "+regexExp.test(learnerEmail))
$("#learner_email").css("background", "#f2f4f5");
$("#bad_email_alert").css("display", "none");
$("#submit_button").css("pointer-events", "auto");
}
}
}, 500)
}
document.addEventListener('keyup', checkIfInputsExist);
console.log("Finger Picked up")
</script>

View File

@ -0,0 +1,23 @@
{% include "header" %}
{% include "course_version_outdated_alert", courses: courses.in_catalog %}
<main class="np-main np-catalog np-subpage-container np-max-width">
<div class="np-catalog-header-wrapper">
<div class="np-catalog-header">
<div class="np-resource-title">{{ catalog.headline }}</div>
<div class="np-resource-subtitle">{{ catalog.subheadline }}</div>
</div>
{% capture label %}
{% t shared.filters.by_category %}{% endcapture %}
{% comment %} {% if courses.in_catalog.any? %}
{%
include "filter_dropdown",
filters: courses.filters,
key: "category_uuid",
label: label
%}
{% endif %} {% endcomment %}
</div>
{% include "courses_catalog" %}
</main>
{% include "footer" %}

View File

@ -0,0 +1,132 @@
{% if course.enrolled? %}
<script>
if (document.referrer.includes("/app/learning_paths")) {
window.location.replace("{% route course_viewer, course_id: course.id, learning_path_id: params.learning_path_id %}")
}
</script>
{% else %}
<script>
if (document.referrer.includes("/app/learning_paths")) {
window.location.replace("{% route course_enrollment, code: course.enrollment_code %}")
}
</script>
{% endif %}
{% include "header" %}
<main class="np-main np-max-width np-page-container">
<div class="np-hidden-mobile" id="course-desktop">
{% include "course_desktop_view" %}
</div>
<div class="np-hidden-desktop" id="course-mobile">
{% include "course_mobile_view" %}
</div>
</main>
{% include "section_datasnipper_expert" %}
{% include "footer" %}
<style>
.np-page-container #course-desktop > .np-card-container {
border-radius: 12px;
}
.np-grid-spacing {
padding-left: 0;
padding-right: 5%;
}
.course-main-info,
.np-top-cta {
background: transparent;
padding: 0;
margin-bottom: 32px;
display: block;
}
.course-main-info .np-top-title {
color: #011638;
font-size: 36px;
font-weight: 600;
line-height: 40px;
letter-spacing: -0.48px;
margin-bottom: 12px;
}
.course-main-info .progress-wrapper {
align-items: center;
}
.course-main-info .np-progress-bar-container {
max-width: 400px;
margin: 24px 0;
border-radius: 8px;
background: #E6E8EB;
height: 12px;
}
.course-main-info .np-card-progress-bar {
border-radius: 8px;
height: 12px;
}
.course-main-info .np-top-cta-progress-text {
font-size: 16px;
font-weight: 600;
margin-left: 12px;
margin-top: 0;
color: #5964B7;
}
/* OUTLINE STYLES */
.np-course-outline {
margin-top: 16px;
}
.np-course-outline-title,
.np-card-heading {
opacity: 1;
font-size: 22px;
text-transform: none;
margin-bottom: 24px;
color: #011638;
font-weight: 600;
}
.np-course-outline-content-section-list {
margin-bottom: 20px;
}
.np-course-outline-content-section-name {
font-weight: 600;
border-bottom: none;
padding-bottom: 0;
}
.np-course-outline-content-activity-list {
border: none;
padding: 14px 0;
}
.np-course-outline-content-activity-list-bar {
top: 33px;
}
.np-content-categories-content-item {
background-color: #E7E9F5;
color: #011638;
margin-bottom: 12px;
}
.np-course-outline-content-activity-link {
color: #011638;
}
.np-course-outline-content-activity-link:hover {
color: #0d21a1;
}
.np-flex {
flex-wrap: wrap;
}
</style>

View File

@ -0,0 +1,72 @@
{% include "header" %}
{% include "course_version_outdated_alert", courses: courses.enrolled %}
{% include "sub_navigation" %}
<main class="np-main np-courses np-subpage-container np-max-width">
<div class="np-resource-title">
My courses
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-7 col-lg-9">
{% include "courses_index", class: "col-xs-12 col-md-6" %}
</div>
<div class="col-xs-12 col-sm-6 col-md-5 col-lg-3">
{% include "filter_sidebar_courses" %}
</div>
</div>
</main>
{% include "section_datasnipper_expert" %}
{% include "footer" %}
<style>
.np-resource-title {
margin-bottom: 32px;
}
@media(min-width:768px) {
.row .np-card.course-card {
padding: 0 16px 48px;
}
.row-with-thumbnails {
margin-left: -16px;
margin-right: -16px;
}
}
</style>
{% comment %} <script>
const categoryFilters = document.querySelectorAll(".category-filter")
const courseColumns = document.querySelectorAll(".course-columns")
categoryFilters.forEach((filter) => {
filter.addEventListener("click", function(e) {
setActiveFilter(e.target)
filterCourses(e.target.getAttribute("data-cat"))
})
})
function setActiveFilter(selectedFilter) {
categoryFilters.forEach((filter) => {
filter.classList.remove("active")
})
selectedFilter.classList.add("active")
}
function filterCourses(filter) {
courseColumns.forEach((col) => {
col.style.display = "none"
})
courseColumns.forEach((col) => {
if (col.getAttribute("data-categories").includes(filter)) {
col.style.display = "flex"
}
})
}
</script> {% endcomment %}

View File

@ -0,0 +1,115 @@
{% include "header" %}
{% include "course_version_outdated_alert", courses: courses.enrolled %}
{% include "sub_navigation" %}
<main class="np-main np-courses np-subpage-container np-max-width">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-7 col-lg-9">
<div class="np-resource-title">
My Courses
</div>
{% include "courses_index", class: "col-xs-12 col-md-6 col-lg-4 np-stretch-content" %}
<div class="np-resource-title">
Available Courses
</div>
{% if courses.in_catalog.any? %}
<div class="np-catalog-courses row row-with-thumbnails">
{% for course in courses.in_catalog %}
{% unless course.enrolled? %}
<div class="col-xs-12 col-md-6 col-lg-4 np-stretch-content">
{% include "cards_course" with course %}
</div>
{% endunless %}
{% endfor %}
</div>
{% else %}
{% capture message %}
{% t shared.zero_state.courses.catalog
, key: current_school.course_vocabulary %}
{% endcapture %}
{% include "courses_zero_state", message: message %}
{% endif %}
</div>
{% if features.training_events? %}
<div class="col-xs-12 col-sm-6 col-md-5 col-lg-3">
<div class="dashboard-events">
<div class="np-dashboard-resources-title">
{% t .upcoming_events %}
</div>
{% include "training_events_dashboard" %}
</div>
</div>
{% endif %}
</div>
</main>
{% include "section_datasnipper_expert" %}
{% include "footer" %}
<style>
.np-resource-title {
margin-bottom: 32px;
}
.np-dashboard-resources-title {
color: #fff;
text-transform: capitalize;
margin-bottom: 40px;
font-size: 36px;
line-height: 40px;
font-weight: 600;
}
.np-zero-state-text {
color:#fff;
}
@media(min-width:768px) {
.row .np-card.course-card {
padding: 0 10px 48px;
}
.row-with-thumbnails {
margin-left: -16px;
margin-right: -16px;
}
.dashboard-events .np-card.training-event-card {
padding-left:0;
padding-right:0;
}
}
</style>
{% comment %} <script>
const categoryFilters = document.querySelectorAll(".category-filter")
const courseColumns = document.querySelectorAll(".course-columns")
categoryFilters.forEach((filter) => {
filter.addEventListener("click", function(e) {
setActiveFilter(e.target)
filterCourses(e.target.getAttribute("data-cat"))
})
})
function setActiveFilter(selectedFilter) {
categoryFilters.forEach((filter) => {
filter.classList.remove("active")
})
selectedFilter.classList.add("active")
}
function filterCourses(filter) {
courseColumns.forEach((col) => {
col.style.display = "none"
})
courseColumns.forEach((col) => {
if (col.getAttribute("data-categories").includes(filter)) {
col.style.display = "flex"
}
})
}
</script> {% endcomment %}

View File

@ -0,0 +1,11 @@
{% include "header" %}
<main class="np-main np-homepage">
{% include "homepage_section_welcome" %}
{% include "homepage_section_upcoming_events" %}
{% include "homepage_section_my_courses" %}
{% include "section_datasnipper_expert" %}
</main>
{% include "footer" %}

View File

@ -0,0 +1,313 @@
/*
Put your custom overlay styles in here
You can use your northpass color palette in this file
{{ color_palette.button_font_color }}
{{ color_palette.button_color }}
{{ color_palette.button_hover_color }}
{{ color_palette.header_font_color }}
{{ color_palette.header_font_hover_color }}
{{ color_palette.header_color }}
*/
body {
font-family: "Jost", Arial, sans-serif;
color: #011638;
}
.np-sub-navigation {
display: none;
}
body,
.np-dashboard,
.np-learning-paths {
background-color: #011638;
}
.np-button {
transition: all 0.2s;
border-radius: 6px;
padding: 10px 14px;
font-size: 16px;
font-weight: 600;
line-height: 24px;
}
.np-button.np-button-white {
background-color: #fff;
color: #011638;
}
.np-card-ribbon {
background-color: #01bfb2;
}
.np-homepage {
margin-bottom: 0;
}
.np-subpage-container {
padding-left: 16px;
padding-right: 16px;
}
.np-card-container {
box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.12);
border-radius: 0;
}
.np-card-image {
border-radius: 0;
}
.np-resource-title,
.np-resource-subtitle {
color: #fff;
}
.np-resource-title {
font-size: 32px;
font-weight: 600;
line-height: 40px;
letter-spacing: -0.4px;
}
@media(min-width:768px) {
.np-subpage-container {
padding-left: 0;
padding-right: 0;
}
.np-resource-title {
font-size: 40px;
line-height: 48px;
}
}
/* INSTRUCTORS */
.np-content-instructors-content-item {
display: flex;
align-items: center;
margin-bottom:12px;
}
.np-content-instructors-content-image {
border-radius: 50%
}
.np-content-instructors-content-description {
font-size: 14px;
font-weight: 600;
line-height: 20px;
}
.np-card .np-content-instructors-content-image {
width: 40px;
height: 40px;
}
/* COURSE CARDS */
.np-card .np-card-container {
border-radius: 12px;
padding: 24px;
box-shadow: none;
}
.course-card .np-progress-bar-container {
margin-bottom: 24px;
margin-top: 0;
height: 12px;
background-color: #E6E8EB;
}
.course-card .np-progress-bar-container .np-card-progress-bar {
min-width: 12px;
height: 12px;
background-color: #0D21A1;
}
.course-card .np-card-content-title {
margin: 16px 0 12px;
color: #011638;
font-size: 24px;
font-weight: 600;
line-height: 32px;
text-decoration: none;
}
.course-card a.np-card-content-title:hover {
text-decoration: underline;
}
.course-card .np-card-content-desc {
font-size: 16px;
font-weight: 400;
line-height: 24px;
color: #505C72;
}
.course-info-wrapper,
.event-info-wrapper {
display: flex;
align-items: center;
margin-bottom: 16px;
justify-content:space-between;
}
.course-info,
.event-info {
background-color: #E7E9F5;
color: #0D21A1;
border-radius: 8px;
padding: 4px;
font-size: 12px;
font-weight: 600;
line-height: 18px;
text-align: center;
display: flex;
align-items: center;
}
.course-info-wrapper .course-level,
.event-info-wrapper .event-date {
border-radius: 6px;
background-color: #fff;
padding: 2px 8px;
}
.course-info-wrapper .course-length,
.event-info-wrapper .event-time {
margin: 0 6px;
}
.course-card .np-button {
margin-left: auto;
}
@media(min-width:768px) {
.np-card {
height: 100%;
}
.course-card .np-card-content-title {
font-size: 26px;
line-height: 34px;
}
.np-content-instructors-content-item {
margin-right: 12px;
}
.np-content-instructors-content-description {
margin-left: 8px;
}
}
/* EVENTS CARDS */
.training-event-card .np-card-content-training-event {
padding: 0;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.training-event-card .np-card-content-title {
margin: 0 0 12px;
color: #011638;
font-size: 24px;
font-weight: 600;
line-height: 32px;
text-decoration:none;
}
.training-event-card a.np-card-content-title:hover {
text-decoration: underline;
}
.training-event-card .np-card-content-subtitle {
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 24px;
color: #505C72;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
overflow: hidden;
text-overflow: ellipsis;
}
.training-event-card .np-card-content {
margin-top: 24px;
align-items: flex-end;
justify-content: space-between;
}
.training-event-card .session-status-label {
font-size: 14px;
color: #01bfb2;
font-weight: 600;
}
@media(min-width:768px) {
.training-event-card {
min-height:350px;
}
.training-event-card .np-card-content-title {
font-size: 30px;
line-height: 38px;
}
}
/* LEARNING PATH CARDS */
.np-learning-path .np-card-content-title {
font-size: 24px;
font-weight: 600;
color: #011638;
}
.np-learning-path .np-card-progress-bar-container,
.np-learning-path .np-card-progress-bar {
height:12px;
}
/* SEARCH PAGE STYLES */
.np-resource-subtitle-number,
.np-resource-subtitle span.np-button-color {
color: #01bfb2 !important;
font-weight: 600
}
/* LEARNING PATH PAGE */
.np-learning-path-outline-item,
#learning-path-desktop .np-resource-header-card,
#learning-path-desktop .np-top-cta,
#learning-path-mobile .np-top-cta,
#learning-path-mobile .np-card-container,
#learning-path-desktop .np-card-container {
border-radius:12px;
}
#learning-path-mobile .np-resource-header .np-top-title,
#learning-path-mobile .np-resource-header .np-text-title {
color:#fff;
}
.np-learning-path-outline-item {
background-color:#fff;
border:none;
}
.np-learning-path-outline-name .np-top-title,
.np-top-cta-progress-title.np-text-title {
color:#011638;
font-weight:600;
}
.np-learning-path-outline-icon {
color:#0d21a1;
}

View File

@ -0,0 +1,25 @@
{% include "header" %}
{% include "sub_navigation" %}
<main class="np-main np-training-events np-subpage-container np-max-width">
<div class="row">
<div class="col-xs-12 col-sm-10">
<div class="np-resource-title">
{% t.title %}
</div>
<div class="np-resource-subtitle">
{% t.subtitle %}
</div>
</div>
<div class="col-xs-12 col-sm-2">
{% include "training_events_filter" %}
</div>
</div>
{% include "training_events_index" %}
</main>
{% include "footer" %}
<script>
document.addEventListener("DOMContentLoaded", function() {
updateEventTimezone()
})
</script>

View File

@ -0,0 +1,114 @@
{% include "header" %}
<main class="np-main np-training-session np-max-width np-page-container">
<div class="np-hidden-mobile" id="training-session-desktop">
{% include "training_session_desktop_view" %}
</div>
<div class="np-hidden-desktop" id="training-session-mobile">
{% include "training_session_mobile_view" %}
</div>
</main>
{% include "footer" %}
<style>
.np-training-session-sessions-title,
.np-training-session-zero-state-text {
color: #fff;
}
.np-resource-header-card,
.np-training-session .np-card-container {
border-radius:12px;
}
.np-training-session-tile {
background-color: #E7E9F5;
border-radius: 12px;
color: #0C176C;
}
.np-training-session-tile:hover {
background-color: #fff;
}
.np-training-session-tile-icon,
.np-training-session-tile-chevron,
.np-icon-back {
color: #0C176C;
}
.np-training-session .np-top-title,
.np-training-session .np-text-title {
color:#011638;
}
</style>
<script>
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var day = "{{ training_session.day }}"
var month = "{{ training_session.month }}"
var year = "{{ training_session.year }}"
var timePeriod = document.querySelector("div.np-training-session-time > span:nth-child(2)").innerHTML.split(' - ')
var startTime = timePeriod[0];
var endTime = timePeriod[1];
var shortTimezone = document.querySelector("div.np-training-session-time > span:nth-child(3)").innerHTML
if (shortTimezone == "CET") {
shortTimezone = "GMT+0100"
} else if (shortTimezone == "CEST") {
shortTimezone = "GMT+0200"
}
var startDate = new Date(`${day} ${month} ${year} ${startTime} ${shortTimezone}`);
var endDate = new Date(`${day} ${month} ${year} ${endTime} ${shortTimezone}`);
var userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
var userTimeZoneAbbreviation = new Date().toLocaleTimeString('en-us',{timeZone: userTimeZone, timeZoneName:'short'}).split(' ')[2];
var startFormatedTime = formatAMPM(startDate)
var endFormatedTime = formatAMPM(endDate)
document.querySelector("div.np-training-session-time > span:nth-child(2)").innerHTML = `${startFormatedTime} - ${endFormatedTime}`
document.querySelector("div.np-training-session-time > span:nth-child(3)").innerHTML = userTimeZoneAbbreviation
document.querySelector(".np-card-training-session-date-day").innerHTML = startDate.getDate()
document.querySelectorAll(".np-training-session-tile").forEach((element) => {
var extraStartTime = element.querySelector('.np-training-session-tile-time').innerHTML.split(' - ')[0].trim()
var extraEndTime = element.querySelector('.np-training-session-tile-time').innerHTML.split(' - ')[1].trim()
var extraEndTimeFinal = `${extraEndTime.split(' ')[0]} ${extraEndTime.split(' ')[1]}`
var extraTimeZone = extraEndTime.split(' ')[2]
console.log(extraEndTime)
if (extraTimeZone == "CET") {
extraTimeZone = "GMT+0100"
} else if (extraTimeZone == "CEST") {
extraTimeZone = "GMT+0200"
}
var extraYear = element.querySelector('.np-training-session-tile-date').innerHTML.split(', ')[1].trim()
var extraMonth = element.querySelector('.np-training-session-tile-date').innerHTML.split(', ')[0].trim().split(' ')[0]
var extraDay = element.querySelector('.np-training-session-tile-date').innerHTML.split(', ')[0].trim().split(' ')[1]
var extraStartDate = new Date(`${extraDay} ${extraMonth} ${extraYear} ${extraStartTime} ${extraTimeZone}`);
var extraEndDate = new Date(`${extraDay} ${extraMonth} ${extraYear} ${extraEndTimeFinal} ${extraTimeZone}`);
var extraUserTimeZone = Intl.DateTimeFormat().resolvedOptions().extraTimeZone;
var extraUserTimeZoneAbbreviation = new Date().toLocaleTimeString('en-us',{timeZone: extraUserTimeZoneAbbreviation, timeZoneName:'short'}).split(' ')[2];
var extraStartFormatedTime = formatAMPM(extraStartDate)
var extraEndFormatedTime = formatAMPM(extraEndDate)
element.querySelector('.np-training-session-tile-time').innerHTML = `${extraStartFormatedTime} - ${extraEndFormatedTime} ${extraUserTimeZoneAbbreviation}`
element.querySelector('.np-training-session-tile-date').innerHTML = `${monthNames[extraStartDate.getMonth()]} ${extraStartDate.getDate()}, ${extraStartDate.getFullYear()}`
})
function formatAMPM(date) {
var hours = date.getHours();
var minutes = date.getMinutes();
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes < 10 ? '0'+minutes : minutes;
var strTime = hours + ':' + minutes + ' ' + ampm;
return strTime;
}
</script>

View File

@ -0,0 +1,163 @@
{% assign events_to_show = "Introduction to DataSnipper, Introduction to the Financial Statement Suite, Automation with DataSnipper, Welcome to the Financial Statement Suite, DataSnipper Tips & Tricks, DataSnipper Q&A, Financial Statement Suite Tips & Tricks" | split: ", " %}
{% include "header" %}
{% include "sub_navigation" %}
<main class="np-main np-training-events np-subpage-container np-max-width">
<div class="row">
<div class="col-xs-12 col-sm-10">
<div class="np-resource-title">
{{ custom_page.headline }}
</div>
<div class="np-resource-subtitle">
{{ custom_page.subheadline }}
</div>
</div>
</div>
<div class="row events-filters-row">
<div class="event-filter active" data-filter="all">All</div>
<div class="event-filter" data-filter="datasnipper">DataSnipper</div>
<div class="event-filter" data-filter="financial statement suite">Financial Statement Suite</div>
<div class="event-filter" data-filter="interactive learning">Interactive Learning</div>
</div>
<div class="np-dashboard-resources">
{% if training_events.available.any? %}
<div class="row row-with-thumbnails training-sessions">
{% for training_event in training_events.available %}
{% if events_to_show contains training_event.title %}
{% for session in training_event.sessions %}
{% assign session_date = session.year | append: "-" | append: session.month | append: "-" | append: session.day %}
<div class="col-xs-12 col-sm-6 col-lg-4 np-stretch-content event-item" data-date="{{ session_date | date: '%s'}}">
<div class="np-card training-event-card">
<div class="np-card-container">
<div class="event-info-wrapper">
<div class="event-info">
<div class="event-date">{{ session.day }} {{ session.month | date: "%b" }}</div>
<div class="event-time">{{ session.starts }}</div>
<div class="hidden-event-info np-hidden">
<span class="event-year">{{ session.year }}</span>
<span class="event-timezone">{{ session.time_zone }}</span>
</div>
</div>
{% if session.registered? %}
<div class="session-status-label">Registered
<i class="far fa-check np-training-session-icon"></i>
</div>
{% endif %}
</div>
<div class="np-card-content-training-event">
<a class="np-card-content-title" href="{% route training_session, id: session.id %}">{{ training_event.title | strip }}</a>
<div class="np-card-content-subtitle">
{{ training_event.description | strip_html }}
</div>
</div>
<div class="np-card-content">
<div class="event-instructor">{{ session.instructor }}</div>
<a class="np-button np-button-wide" href="{% route training_session, id: session.id %}">
{% t shared.view %} event
</a>
</div>
</div>
</div>
</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
{% else %}
{% include "training_events_zero_state" %}
{% endif %}
</div>
</main>
{% include "footer" %}
<style>
.events-filters-row {
justify-content: center;
margin: 16px 0 32px;
}
.event-filter {
padding: 12px 24px;
border: 1px solid #E7E9F5;
color: #fff;
margin: 16px;
cursor: pointer;
border-radius: 4px;
font-weight: 500;
}
.event-filter.active,
.event-filter:hover {
border: 1px solid #E7E9F5;
background-color: #E7E9F5;
color: #0D21A1;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function() {
const eventItems = document.querySelectorAll(".event-item")
const eventFilters = document.querySelectorAll('.event-filter')
updateEventTimezone()
reorderTilesBySessionDate()
eventFilters.forEach((filter) => {
filter.addEventListener("click", function() {
eventFilters.forEach((filterItems) => { filterItems.classList.remove("active") })
const selectedFilter = filter.getAttribute("data-filter")
this.classList.add("active")
if (selectedFilter == "all") {
eventItems.forEach((item) => { item.style.display = "flex" })
} else {
eventItems.forEach((item) => { item.style.display = "none" })
if (selectedFilter == "datasnipper") {
eventItems.forEach((item) => {
const eventTitle = item.querySelector(".np-card-content-title").innerText.toLowerCase().trim()
if (eventTitle == "automation with datasnipper" || eventTitle == "datasnipper q&a" || eventTitle == "datasnipper tips & tricks") {
item.style.display = "flex"
}
})
} else if (selectedFilter == "financial statement suite") {
eventItems.forEach((item) => {
const eventTitle = item.querySelector(".np-card-content-title").innerText.toLowerCase().trim()
if (eventTitle == "welcome to the financial statement suite" || eventTitle == "financial statement suite tips & tricks") {
item.style.display = "flex"
}
})
} else if (selectedFilter == "interactive learning") {
eventItems.forEach((item) => {
const eventTitle = item.querySelector(".np-card-content-title").innerText.toLowerCase().trim()
if (eventTitle == "datasnipper q&a" || eventTitle == "datasnipper tips & tricks" || eventTitle == "financial statement suite tips & tricks") {
item.style.display = "flex"
}
})
}
}
})
})
})
function reorderTilesBySessionDate() {
var indexes = document.querySelectorAll(".event-item");
var indexesArray = Array.from(indexes);
const sortByDate = arr => {
const positionSorter = (a, b) => {
return a.dataset.date - b.dataset.date;
}
arr.sort(positionSorter);
};
sortByDate(indexesArray);
document.querySelectorAll('.event-item').forEach(e => e.remove());
indexesArray.forEach(e => document.querySelector(".training-sessions").appendChild(e));
}
</script>

View File

@ -21,3 +21,14 @@ Catalog page:
* merina design platform - super detail (how many pixels a box should be)
* Branding team is strict, but good at feedback. They will let us take a first pass and then give us feedback.
* Make this design iterative!
## 1/25/2024
### Post-launch!
Correct Cert URL: `https://chubb.northpass.com/app/certificate/d5f601c5-5677-4177-9cc3-4041c8030290`
TODO: Ask Marek about custom LP notifications and adding a cert URL. {{ certificate.url }} --> is this possible?
Learning path strings together )completion page button)
custom learning path button end of course screen