Skip to content

Commit f70e24f

Browse files
authored
Merge pull request #2811 from themeum/v4-blind
♻️ Dashboard chart, account photo UX, progress threshold, and component refactors
2 parents 7c0fb6e + c1896be commit f70e24f

19 files changed

Lines changed: 209 additions & 232 deletions

File tree

assets/core/scss/components/_progress.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
&-fill {
1414
--tutor-progress-width: 0%;
15+
--tutor-progress-start: 0%;
1516
height: 100%;
1617
width: 100%;
1718
transform: translateX(calc(var(--tutor-progress-width) - 100%));
@@ -85,7 +86,7 @@
8586

8687
@keyframes tutor-progress-fill-animate {
8788
from {
88-
transform: translateX(-100%);
89+
transform: translateX(calc(var(--tutor-progress-start, 0%) - 100%));
8990
}
9091
to {
9192
transform: translateX(calc(var(--tutor-progress-width) - 100%));

assets/core/scss/mixins/_avatars.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
}
1616

1717
@mixin tutor-avatar-image {
18+
position: absolute;
19+
inset: 0;
1820
width: 100%;
1921
height: 100%;
2022
object-fit: cover;

assets/src/js/frontend/dashboard/pages/instructor/home-charts.ts

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const CHART_CONFIG = {
6868
statCardHeight: '33px',
6969
width: '100%',
7070
overviewMaxHeight: 179,
71-
completionMaxHeight: 60,
71+
completionMaxHeight: 118,
7272
},
7373

7474
aspectRatio: {
@@ -88,7 +88,7 @@ const CHART_CONFIG = {
8888
},
8989

9090
bar: {
91-
thickness: 54,
91+
thickness: 118,
9292
borderRadius: 5,
9393
borderWidth: 3,
9494
},
@@ -140,17 +140,45 @@ const getCSSProperty = (element: HTMLElement, propertyName: string): string => {
140140
return getComputedStyle(element).getPropertyValue(propertyName).trim();
141141
};
142142

143-
const getAnimationConfig = (): { duration: 0 } | undefined => {
143+
const shouldReduceMotion = (): boolean => {
144144
const wrapper = document.querySelector('[data-tutor-theme]') || document.documentElement;
145145
const motion = wrapper.getAttribute('data-tutor-motion');
146+
return (
147+
motion === 'reduce' ||
148+
((!motion || motion === 'auto') && window.matchMedia('(prefers-reduced-motion: reduce)').matches)
149+
);
150+
};
146151

147-
if (motion === 'reduce') {
152+
const getAnimationConfig = (): { duration: 0 } | undefined => {
153+
if (shouldReduceMotion()) {
148154
return { duration: 0 };
149155
}
150-
if ((!motion || motion === 'auto') && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
156+
return undefined;
157+
};
158+
159+
const getCompletionChartAnimation = (): { duration: 0 } | Record<string, unknown> => {
160+
if (shouldReduceMotion()) {
151161
return { duration: 0 };
152162
}
153-
return undefined;
163+
164+
return {
165+
base: { duration: 0 },
166+
x: {
167+
from: (ctx: Record<string, unknown>) => {
168+
const chart = ctx.chart as {
169+
scales: { x: { getPixelForValue: (v: number) => number } };
170+
data: { datasets: Array<{ data: Array<number> }> };
171+
};
172+
const dataIndex = ctx.dataIndex as number;
173+
const datasetIndex = ctx.datasetIndex as number;
174+
let cumulative = 0;
175+
for (let i = 0; i < datasetIndex; i++) {
176+
cumulative += chart.data.datasets[i].data[dataIndex] || 0;
177+
}
178+
return chart.scales.x.getPixelForValue(cumulative);
179+
},
180+
},
181+
};
154182
};
155183

156184
const createChart = (canvas: HTMLCanvasElement, config: ChartConfiguration): void => {
@@ -791,6 +819,9 @@ export const courseCompletionChart = (data: CourseCompletionChartData) => ({
791819
const chartColors = [colors.enrolled, colors.completed, colors.in_progress, colors.inactive, colors.cancelled];
792820
const dataKeys: CourseCompletionChartDataKey[] = ['enrolled', 'completed', 'in_progress', 'inactive', 'cancelled'];
793821

822+
const lastNonZeroIndex = chartData.reduce((last, value, i) => (value > 0 ? i : last), -1);
823+
const firstNonZeroIndex = chartData.findIndex((value) => value > 0);
824+
794825
return {
795826
type: 'bar',
796827
data: {
@@ -800,20 +831,29 @@ export const courseCompletionChart = (data: CourseCompletionChartData) => ({
800831
backgroundColor: chartColors[index],
801832
barThickness: CHART_CONFIG.bar.thickness,
802833
borderRadius: {
803-
bottomLeft: index === 0 ? CHART_CONFIG.bar.borderRadius : 0,
804-
topLeft: index === 0 ? CHART_CONFIG.bar.borderRadius : 0,
805-
bottomRight: index === chartData.length - 1 ? CHART_CONFIG.bar.borderRadius : 0,
806-
topRight: index === chartData.length - 1 ? CHART_CONFIG.bar.borderRadius : 0,
834+
bottomLeft: index === (firstNonZeroIndex > -1 ? firstNonZeroIndex : 0) ? CHART_CONFIG.bar.borderRadius : 0,
835+
topLeft: index === (firstNonZeroIndex > -1 ? firstNonZeroIndex : 0) ? CHART_CONFIG.bar.borderRadius : 0,
836+
bottomRight:
837+
index === (lastNonZeroIndex > -1 ? lastNonZeroIndex : chartData.length - 1)
838+
? CHART_CONFIG.bar.borderRadius
839+
: 0,
840+
topRight:
841+
index === (lastNonZeroIndex > -1 ? lastNonZeroIndex : chartData.length - 1)
842+
? CHART_CONFIG.bar.borderRadius
843+
: 0,
807844
},
808845
borderSkipped: false,
809846
borderWidth: {
810-
right: index === chartData.length - 1 ? 0 : CHART_CONFIG.bar.borderWidth,
847+
right:
848+
index === (lastNonZeroIndex > -1 ? lastNonZeroIndex : chartData.length - 1)
849+
? 0
850+
: CHART_CONFIG.bar.borderWidth,
811851
},
812852
borderColor: getCSSProperty(this.$refs.canvas, '--tutor-surface-l1'),
813853
})),
814854
},
815855
options: {
816-
animation: getAnimationConfig(),
856+
animation: getCompletionChartAnimation(),
817857
indexAxis: 'y',
818858
responsive: CHART_CONFIG.common.responsive,
819859
maintainAspectRatio: false,

assets/src/js/v3/entries/course-builder/components/modals/QuizModal.tsx

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useRef, useState } from 'react';
1+
import { Fragment, useEffect, useRef, useState } from 'react';
22
import { Controller, FormProvider } from 'react-hook-form';
33
import { css } from '@emotion/react';
44
import { __ } from '@wordpress/i18n';
@@ -393,22 +393,30 @@ const QuizModal = ({
393393
triggerRef={cancelRef}
394394
closePopover={() => setIsConfirmationOpen(false)}
395395
maxWidth="258px"
396-
title={__('Your quiz has unsaved changes. If you cancel, you will lose your progress.', 'tutor')}
397-
message={__('Are you sure you want to continue?', 'tutor')}
396+
title={
397+
<div css={styles.confirmationPopoverTitle}>
398+
<SVGIcon name="warning" width={20} height={20} />
399+
<span>{__('Discard changes?', 'tutor')}</span>
400+
</div>
401+
}
402+
message={''}
398403
animationType={AnimationType.slideUp}
399404
placement={
400405
CURRENT_VIEWPORT.isAboveMobile ? POPOVER_PLACEMENTS.BOTTOM : POPOVER_PLACEMENTS.ABSOLUTE_CENTER
401406
}
402407
positionModifier={{ top: -55, left: quizId ? 34 : 2 }}
403408
confirmButton={{
404-
text: __('Yes', 'tutor'),
409+
text: __('Keep Editing', 'tutor'),
405410
variant: 'primary',
406411
}}
407412
cancelButton={{
408-
text: __('No', 'tutor'),
413+
text: __('Discard', 'tutor'),
409414
variant: 'text',
410415
}}
411416
onConfirmation={() => {
417+
setIsConfirmationOpen(false);
418+
}}
419+
onCancel={() => {
412420
form.reset();
413421
setValidationError(null);
414422

@@ -420,6 +428,7 @@ const QuizModal = ({
420428
if (!quizId) {
421429
closeModal();
422430
}
431+
setIsConfirmationOpen(false);
423432
}}
424433
/>
425434
</ModalWrapper>
@@ -454,6 +463,16 @@ const styles = {
454463
}
455464
}
456465
`,
466+
confirmationPopoverTitle: css`
467+
${styleUtils.display.flex()};
468+
align-items: center;
469+
gap: ${spacing[8]};
470+
margin-bottom: ${spacing[8]};
471+
472+
svg {
473+
color: ${colorTokens.icon.default};
474+
}
475+
`,
457476
left: css`
458477
border-right: 1px solid ${colorTokens.stroke.divider};
459478
${styleUtils.overflowYAuto};

assets/src/js/v3/shared/molecules/ConfirmationPopover.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import Popover from './Popover';
1515
interface ConfirmationPopoverProps<TRef> {
1616
triggerRef: RefObject<TRef>;
1717
isOpen: boolean;
18-
title: string;
18+
title: string | ReactNode;
1919
message: string | ReactNode;
2020
onConfirmation: () => void;
2121
onCancel?: () => void;

assets/src/scss/frontend/dashboard/pages/_instructor-dashboard.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@
6767
padding: $tutor-spacing-6;
6868

6969
canvas {
70-
margin-top: $tutor-spacing-13;
71-
max-height: 60px;
70+
margin-top: $tutor-spacing-5;
71+
max-height: 118px;
7272
width: 100%;
7373
}
7474

assets/src/scss/frontend/kids/_dashboard.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@
6464
@include tutor-kids-shadow(false, $tutor-border-idle, $tutor-radius-6xl, sm);
6565
}
6666

67+
.tutor-account-section #tutor-account-form .tutor-card {
68+
border-radius: $tutor-radius-6xl;
69+
}
70+
71+
.tutor-account-section .tutor-account-cover-photo {
72+
border-radius: $tutor-radius-4xl;
73+
}
74+
6775
.tutor-progress-card .tutor-progress-card-thumbnail,
6876
.tutor-subscription-overview-card,
6977
.tutor-subscription-payments-list,

assets/src/scss/frontend/kids/_learning-area.scss

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@
7373
border-bottom-right-radius: $tutor-radius-md;
7474
}
7575

76+
.tutor-lesson-content .tutor-lesson-content-tab {
77+
margin-bottom: $tutor-spacing-2;
78+
}
79+
7680
.tutor-quiz-submission[data-question-layout-view='single_question'],
7781
.tutor-quiz-submission[data-question-layout-view='question_pagination'] {
7882
.tutor-quiz-question {
@@ -81,6 +85,10 @@
8185
}
8286
}
8387

88+
.tutor-learning-area-resources .tutor-resources-wrapper {
89+
gap: $tutor-spacing-5;
90+
}
91+
8492
.tutor-quiz-summary-page .tutor-quiz-review-dnd-rows {
8593
gap: $tutor-spacing-4;
8694
}
@@ -238,8 +246,7 @@
238246
.tutor-meeting,
239247
.tutor-quiz-intro,
240248
.tutor-lesson-content .tutor-lesson-content-tab,
241-
.tutor-quiz-summary .tutor-quiz-result,
242-
.tutor-learning-area-resources .tutor-resources-wrapper {
249+
.tutor-quiz-summary .tutor-quiz-result {
243250
box-shadow: none;
244251
}
245252

assets/src/scss/frontend/learning-area/pages/_course-info.scss

Lines changed: 15 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -34,78 +34,29 @@
3434
margin-top: $tutor-spacing-8;
3535
}
3636

37-
.tutor-course-accordion {
37+
.tutor-course-info-cards {
3838
@include tutor-flex(column);
39-
gap: $tutor-spacing-2;
40-
margin-top: $tutor-spacing-9;
41-
42-
&-item {
43-
background-color: $tutor-surface-l1;
44-
outline: 1px solid $tutor-border-idle;
45-
border-radius: $tutor-radius-lg;
46-
padding: $tutor-spacing-5 $tutor-spacing-6;
47-
48-
&:focus-within {
49-
@include tutor-focus-ring();
50-
}
51-
52-
.tutor-course-accordion-header {
53-
@include tutor-flex(row, center, space-between);
54-
cursor: pointer;
55-
outline: none;
56-
57-
&-title {
58-
@include tutor-typography(medium, medium);
59-
60-
@include tutor-breakpoint-down(sm) {
61-
font-size: $tutor-font-size-small;
62-
line-height: $tutor-font-size-small;
63-
}
64-
}
65-
66-
&-icon {
67-
@include tutor-flex-center();
68-
69-
svg {
70-
@include tutor-transition(transform);
71-
72-
@include tutor-breakpoint-down(sm) {
73-
height: 20px;
74-
width: 20px;
75-
}
76-
}
39+
gap: $tutor-spacing-4;
40+
}
7741

78-
&.is-expanded svg {
79-
transform: rotate(180deg);
80-
}
81-
}
82-
}
42+
.tutor-course-info-list {
43+
@include tutor-grid(2, $tutor-spacing-6);
8344

84-
.tutor-course-accordion-body {
85-
@include tutor-typography(p3);
86-
margin-top: $tutor-spacing-5;
87-
}
45+
@include tutor-breakpoint-down(sm) {
46+
grid-template-columns: 1fr;
8847
}
8948

90-
.tutor-course-accordion-list {
91-
@include tutor-grid(2, $tutor-spacing-6);
92-
93-
@include tutor-breakpoint-down(sm) {
94-
grid-template-columns: 1fr;
95-
}
96-
97-
&-item {
98-
@include tutor-flex(row);
99-
gap: $tutor-spacing-4;
49+
&-item {
50+
@include tutor-flex(row);
51+
gap: $tutor-spacing-4;
10052

101-
svg {
102-
flex-shrink: 0;
103-
}
53+
svg {
54+
flex-shrink: 0;
10455
}
56+
}
10557

106-
&-content {
107-
@include tutor-typography(p3);
108-
}
58+
&-content {
59+
@include tutor-typography(p3);
10960
}
11061
}
11162

assets/src/scss/frontend/learning-area/pages/_index.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44
@forward './course-info';
55
@forward './qna';
66
@forward './quiz-intro';
7-
@forward './resources';
87
@forward './announcements';

0 commit comments

Comments
 (0)