Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
a820935
feat(icons): add dark mode icon
b-l-i-n-d Jul 29, 2026
7a3fc99
feat(brand-logo): add brand logo template and frontend styles
b-l-i-n-d Jul 29, 2026
f0a3ff2
feat(brand-logo): add brand logo settings field
b-l-i-n-d Jul 29, 2026
288c2cc
feat(brand-logo): add brand logo settings field
b-l-i-n-d Jul 29, 2026
ec78aa8
feat(page-elements): replace spotlight mode with page element header/…
b-l-i-n-d Jul 29, 2026
39d57cf
feat(icons): replace dashicons with custom footer svg icon in page el…
b-l-i-n-d Jul 29, 2026
6727240
refactor: remove unused CSS selectors from brand logo and page elemen…
b-l-i-n-d Jul 29, 2026
e7b2912
refactor: rename brand logo CSS classes from BEM to hyphenated
b-l-i-n-d Jul 29, 2026
ceb3978
fix: preserve spotlight mode behavior in page elements default visibi…
b-l-i-n-d Jul 29, 2026
b0adfa7
refactor: Add `show_learning_site` header and footer options check
b-l-i-n-d Jul 29, 2026
0a17681
refactor: Revert unintentional changes
b-l-i-n-d Jul 29, 2026
3332625
refactor: Update code readability
b-l-i-n-d Jul 30, 2026
a29d553
style: Update header positioning
b-l-i-n-d Jul 30, 2026
798ac8b
Merge branch 'dev' into feat/logo
b-l-i-n-d Aug 4, 2026
d64abd6
fix(settings): resolve PHPStan type errors in Options_V2
b-l-i-n-d Aug 4, 2026
11d63b5
refactor(settings): generic image upload list field type
b-l-i-n-d Aug 4, 2026
25965d5
refactor(settings): generic toggle matrix field type
b-l-i-n-d Aug 4, 2026
6e747d1
refactor: Resolve pho stan warning
b-l-i-n-d Aug 4, 2026
164455a
docs: Update since tag
b-l-i-n-d Aug 5, 2026
a2b2a5f
refactor: Update since tag and default values
b-l-i-n-d Aug 5, 2026
32d3157
refactor(settings): make image upload list reusable
b-l-i-n-d Aug 6, 2026
d960a31
refactor: Remove redundant default value
b-l-i-n-d Aug 6, 2026
44576ba
Merge branch 'dev' into feat/logo
b-l-i-n-d Aug 6, 2026
8842a35
feat: Add sidebar logo visbility controll
b-l-i-n-d Aug 6, 2026
02f4327
Merge branch 'dev' into feat/logo
b-l-i-n-d Aug 7, 2026
172c235
feat(learning-area): track theme site-shell header offset
b-l-i-n-d Aug 7, 2026
0de52dd
style(learning-area): Update footer and sidebar style conflict.
b-l-i-n-d Aug 10, 2026
55318c8
docs: Update since tag
b-l-i-n-d Aug 13, 2026
abb1871
refactor: Use ignore-kids to resolve unintentional icon changes
b-l-i-n-d Aug 13, 2026
93d47bc
feat(brand-logo): migrate course builder logo to light brand logo set…
b-l-i-n-d Aug 14, 2026
f40341c
feat(settings): reset image_upload_list and toggle_matrix fields
b-l-i-n-d Aug 14, 2026
aa5ad9a
style(admin): hide isolated course details wrappers when options disa…
b-l-i-n-d Aug 14, 2026
c43ef02
refactor(page-elements): migrate spotlight mode to per-shell visibility
b-l-i-n-d Aug 14, 2026
7c6f665
docs: add project context glossary and learning-area ADR
b-l-i-n-d Aug 14, 2026
c3458fc
feat(learning-area): wrap quiz attempt and details in site shell
b-l-i-n-d Aug 14, 2026
2a9c87b
feat(learning-area): track site-header overlay offset for quiz layout
b-l-i-n-d Aug 14, 2026
3346fec
style(learning-area): bound quiz and summary layout to theme shell
b-l-i-n-d Aug 14, 2026
c9a6487
refactor(dashboard): move mobile nav into dashboard layout flow
b-l-i-n-d Aug 14, 2026
7244b23
refactor(template): centralize site-shell data resolution
b-l-i-n-d Aug 17, 2026
d28fad2
feat(dashboard): apply site-shell offset controller to dashboard layouts
b-l-i-n-d Aug 17, 2026
0d67d6a
style(dashboard): offset dashboard layout beneath theme header in sit…
b-l-i-n-d Aug 17, 2026
cb4a620
fix(quiz): bound quiz summary within site shell and reserve header ov…
b-l-i-n-d Aug 17, 2026
aebe0a2
fix(logo): use site title as logo alt text
b-l-i-n-d Aug 17, 2026
9605c15
refactor(site-shell): move site-shell controller to frontend services
b-l-i-n-d Aug 17, 2026
42fab85
Merge branch dev into feat/logo
b-l-i-n-d Aug 17, 2026
b271225
style: Remove unwanted scss
b-l-i-n-d Aug 17, 2026
c3c5baf
feat(image-upload-list): Add description support
b-l-i-n-d Aug 21, 2026
674e8ef
chore: Remove unnecessary code
b-l-i-n-d Aug 21, 2026
e4d661e
fix(course): guard attachment image url retrieval for brand logo
b-l-i-n-d Aug 24, 2026
de74c63
refactor(template): support header and footer visibility in custom he…
b-l-i-n-d Aug 24, 2026
e5ba0ca
fix(options): add fallback normalization for legacy spotlight mode an…
b-l-i-n-d Aug 24, 2026
b225934
fix(template): add header role heading selector for theme header dete…
b-l-i-n-d Aug 24, 2026
45392e1
docs(options): update @since version tag for image_upload_list
b-l-i-n-d Aug 24, 2026
4c3794c
fix(options): check both header and footer visibility for legacy spot…
b-l-i-n-d Aug 24, 2026
ded4ede
feat(learning-area): move expand button under more pages container an…
b-l-i-n-d Aug 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/icons/dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/footer.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions assets/src/js/admin-dashboard/segments/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,53 @@ document.addEventListener('DOMContentLoaded', function () {
};
}

const allowedBrandLogoMimeTypes = ['image/jpeg', 'image/png'];
Comment thread
b-l-i-n-d marked this conversation as resolved.
Outdated

$(document).on('click', '.tutor-brand-logo-upload-select', function (event) {
event.preventDefault();

const $upload = $(this).closest('.tutor-brand-logo-upload');
const $input = $upload.find('.tutor-brand-logo-upload-input');
const $preview = $upload.find('.tutor-brand-logo-upload-preview');
const $image = $preview.find('img');
const $remove = $upload.find('.tutor-brand-logo-upload-remove');
const frame = wp.media({
title: __('Select a brand logo', 'tutor'),
button: { text: __('Use this logo', 'tutor') },
library: { type: 'image' },
multiple: false,
});

frame.on('select', function () {
const attachment = frame.state().get('selection').first().toJSON();
if (!allowedBrandLogoMimeTypes.includes(attachment.mime)) {
tutor_toast(__('Error!', 'tutor'), __('Please select a JPG, JPEG, or PNG image.', 'tutor'), 'error');
return;
}

$input.val(attachment.id).trigger('change');
$image.attr('src', attachment.url).prop('hidden', false);
$preview.addClass('has-image');
$upload.addClass('has-image');
$remove.prop('hidden', false);
$('#save_tutor_option').prop('disabled', false);
});

frame.open();
});

$(document).on('click', '.tutor-brand-logo-upload-remove', function (event) {
event.preventDefault();

const $upload = $(this).closest('.tutor-brand-logo-upload');
$upload.find('.tutor-brand-logo-upload-input').val('').trigger('change');
$upload.find('.tutor-brand-logo-upload-preview img').attr('src', '').prop('hidden', true);
$upload.find('.tutor-brand-logo-upload-preview').removeClass('has-image');
$upload.removeClass('has-image');
$(this).prop('hidden', true);
$('#save_tutor_option').prop('disabled', false);
});

const validateEmail = (email) => {
const re = /^(([^<>()[\]\\.,;:\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,}))$/;
return re.test(String(email).toLowerCase());
Expand Down
2 changes: 2 additions & 0 deletions assets/src/js/v3/shared/icons/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export const icons = [
'css',
'csv',
'currency',
'dark',
'dbf',
'delete',
'delete2',
Expand Down Expand Up @@ -180,6 +181,7 @@ export const icons = [
'fireDisabled',
'fla',
'font',
'footer',
'freeShippingType',
'gift',
'giftCard',
Expand Down
222 changes: 222 additions & 0 deletions assets/src/scss/admin-dashboard/_tutor-admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,228 @@ body.tutor-backend-tutor_settings #wpbody-content {
border-bottom: none;
}

.tutor-brand-logo-field {
.tutor-brand-logo-list {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 15px;
padding: 12px;
border: 1px solid var(--tutor-border-color);
border-radius: 8px;
width: 100%;
min-width: 0;
}

.tutor-brand-logo-upload {
display: grid;
grid-template-columns: minmax(160px, 1fr) minmax(240px, 320px);
gap: 16px;
min-height: 40px;
align-items: center;
width: 100%;
height: 100%;
min-width: 0;

> *:last-child {
justify-self: end;
}

@include breakpoint-max(782) {
grid-template-columns: 1fr;
gap: 10px;
}
}

.tutor-brand-logo-upload-control {
position: relative;
max-width: 141px;
width: 100%;
}

.tutor-brand-logo-upload-preview {
display: flex;
align-items: center;
justify-content: center;
max-height: 40px;
height: 100%;
padding: 12px;
background: #f7f8fa;
border-radius: 6px;
overflow: hidden;

img {
max-width: 100%;
max-height: 40px;
height: 100%;
object-fit: contain;
}

&:not(.has-image) {
display: none;
}
}

.tutor-brand-logo-upload-actions {
display: none;
position: absolute;
inset: 0;
align-items: center;
justify-content: center;
gap: 10px;
background: rgba(34, 37, 43, 0.72);
border-radius: 6px;

.tutor-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
padding: 6px;
border: 0;
border-radius: 4px;
background: #f3f5fa;
color: var(--tutor-color-primary);
font-size: 20px;
}

.tutor-brand-logo-upload-remove {
background: #e53935;
color: #fff;
}
}

.tutor-brand-logo-upload-preview.has-image:hover .tutor-brand-logo-upload-actions,
.tutor-brand-logo-upload-preview.has-image:focus-within .tutor-brand-logo-upload-actions {
display: flex;
}

.tutor-brand-logo-upload.has-image .tutor-brand-logo-upload-empty {
display: none;
}

.tutor-brand-logo-upload-empty {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: 100%;
height: 100%;
max-height: 40px;
padding: 12px;
border: 1px dashed #d3d4d9;
border-radius: 6px;
background: #f7f8fa;
color: #69738a;
font-size: 13px;

svg {
color: var(--tutor-color-primary);
}
}

.tutor-brand-logo-upload[data-brand-logo-theme='dark'] {
.tutor-brand-logo-upload-preview,
.tutor-brand-logo-upload-empty {
background: #25272d;
}

.tutor-brand-logo-upload-empty {
border-color: #69738a;
color: #b8bdc8;
}
}

@media (hover: none) {
.tutor-brand-logo-upload-preview.has-image .tutor-brand-logo-upload-actions {
display: flex;
}
}

@include breakpoint-max(782) {
.tutor-brand-logo-list {
padding: 0 16px;
}

.tutor-brand-logo-upload {
grid-template-columns: 1fr;
gap: 10px;
padding: 16px 0;
}
}
}

.tutor-page-elements-field {
.tutor-page-elements-matrix {
margin-top: 24px;
border: 1px solid var(--tutor-border-color);
border-radius: 6px;
overflow: hidden;
}

.tutor-page-elements-matrix-head,
.tutor-page-elements-matrix-row {
display: grid;
grid-template-columns: minmax(180px, 1fr) 180px 180px;
align-items: center;
gap: 16px;
padding: 8px 12px;
}

.tutor-page-elements-matrix-row {
padding: 12px;
}

.tutor-page-elements-matrix-head {
background: #fff;
border-bottom: 1px solid var(--tutor-border-color);
font-size: 16px;
font-weight: 500;

.tutor-page-elements-head-icon {
padding: 4px;
background-color: rgba(244, 246, 249, 1);
border-radius: 50%;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
svg {
color: var(--tutor-color-primary);
}

[data-header-icon='true'] {
transform: rotate(180deg);
}
}
}

.tutor-page-elements-matrix-column {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}

.tutor-page-elements-toggle {
justify-self: center;
}

@include breakpoint-max(782) {
.tutor-page-elements-matrix-head,
.tutor-page-elements-matrix-row {
grid-template-columns: minmax(140px, 1fr) 1fr 1fr;
gap: 8px;
padding: 16px;
}

.tutor-page-elements-matrix-row {
font-size: 16px;
}
}
}

.tutor-option-field-row input[type='text'],
.tutor-option-field-row input[type='email'],
.tutor-option-field-row input[type='number'],
Expand Down
15 changes: 15 additions & 0 deletions assets/src/scss/frontend/components/_brand-logo.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Theme-aware Tutor branding shared by the dashboard and learning area.

.tutor-brand-logo-dark {
display: none;
}

[data-tutor-theme='dark'] {
.tutor-brand-logo-light {
display: none;
}

.tutor-brand-logo-dark {
display: inline;
}
}
1 change: 1 addition & 0 deletions assets/src/scss/frontend/components/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
@forward 'quiz-summary';
@forward 'player';
@forward 'tour';
@forward 'brand-logo';
7 changes: 6 additions & 1 deletion assets/src/scss/frontend/dashboard/layout/_sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
border-bottom: 1px solid $tutor-border-idle;
overflow: hidden;


.tutor-brand-logo {
display: block;
max-width: 120px;
}

img {
display: block;
max-width: 120px;
Expand All @@ -43,7 +49,6 @@
}
}
}

.tutor-dashboard-sidebar-nav {
padding: $tutor-spacing-8 $tutor-spacing-6;

Expand Down
15 changes: 15 additions & 0 deletions assets/src/scss/frontend/learning-area/layout/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@
position: sticky;
}

.tutor-has-site-header & {
position: sticky;
top: 0;
}

.tutor-has-site-header.tutor-has-admin-bar & {
@include tutor-breakpoint-up(md) {
top: 32px;
}

@include tutor-breakpoint-between(md, sm) {
top: 46px;
}
}

&-inner {
@include tutor-flex(row, center);

Expand Down
2 changes: 2 additions & 0 deletions classes/Icon.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ final class Icon {
const CSS = 'css';
const CSV = 'csv';
const CURRENCY = 'currency';
const DARK = 'dark';
const DBF = 'dbf';
const DELETE = 'delete';
const DELETE_2 = 'delete-2';
Expand Down Expand Up @@ -196,6 +197,7 @@ final class Icon {
const FIRE_DISABLED = 'fire-disabled';
const FLA = 'fla';
const FONT = 'font';
const FOOTER = 'footer';
const FREE_SHIPPING_TYPE = 'free-shipping-type';
const GIFT = 'gift';
const GIFT_CARD = 'gift-card';
Expand Down
Loading
Loading