Skip to content

Commit dbc6576

Browse files
committed
Merge branch '4.0.0-dev' into v4/courses/quiz-attempts
2 parents f31cc6e + 965f0b0 commit dbc6576

File tree

8 files changed

+189
-314
lines changed

8 files changed

+189
-314
lines changed

assets/core/ts/components/form.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ export const form = (config: FormControlConfig & { id?: string } = {}) => {
375375
const isCheckbox = type === 'checkbox';
376376
const isFile = type === 'file';
377377

378-
const defaultValue = this.values[name] ?? (isCheckbox ? false : '');
378+
const defaultValue = this.values[name] ?? (isCheckbox ? (element?.checked ?? false) : '');
379379

380380
this.fields[name] = {
381381
name,

assets/src/js/frontend/dashboard/pages/settings.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const settings = () => {
7777
saveBillingInfoMutation: null as MutationState<TutorMutationResponse<string>> | null,
7878
saveWithdrawMethodMutation: null as MutationState<TutorMutationResponse<string>> | null,
7979
resetPasswordMutation: null as MutationState<TutorMutationResponse<string>> | null,
80+
handleUpdateNotification: null as MutationState<unknown, unknown> | null,
8081

8182
init() {
8283
if (!this.$el) {
@@ -91,6 +92,15 @@ const settings = () => {
9192
this.handleSaveWithdrawMethod = this.handleSaveWithdrawMethod.bind(this);
9293
this.handleResetPassword = this.handleResetPassword.bind(this);
9394

95+
this.handleUpdateNotification = this.query.useMutation(this.updateNotification, {
96+
onSuccess: (data: TutorMutationResponse<string>) => {
97+
this.toast.success(data?.message ?? __('Notification settings updated', 'tutor'));
98+
},
99+
onError: (error: Error) => {
100+
this.toast.error(convertToErrorMessage(error) || __('Failed to update notification settings', 'tutor'));
101+
},
102+
});
103+
94104
this.fetchCountriesQuery = this.query.useQuery('fetch-countries', () => this.fetchCountries());
95105

96106
this.uploadProfilePhotoMutation = this.query.useMutation(this.uploadProfilePhoto, {
@@ -151,6 +161,32 @@ const settings = () => {
151161
});
152162
},
153163

164+
async updateNotification(payload: Record<string, boolean>) {
165+
const transformedPayload = Object.keys(payload).reduce(
166+
(formattedPayload, key) => {
167+
const value = payload[key];
168+
const stringValue = typeof value === 'boolean' ? (value ? 'on' : 'off') : value;
169+
170+
if (!key.includes('__')) {
171+
formattedPayload[`tutor_notification_preference[${key}]`] = stringValue;
172+
return formattedPayload;
173+
}
174+
175+
const [firstPart, secondPart] = key.split('__');
176+
if (!firstPart && !secondPart) {
177+
return formattedPayload;
178+
}
179+
180+
formattedPayload[`tutor_notification_preference[email][${firstPart}][${secondPart}]`] = stringValue;
181+
182+
return formattedPayload;
183+
},
184+
{} as Record<string, string>,
185+
);
186+
187+
return wpAjaxInstance.post(endpoints.UPDATE_PROFILE_NOTIFICATION, transformedPayload).then((res) => res.data);
188+
},
189+
154190
async fetchCountries() {
155191
return await axios.get(`${tutorConfig.tutor_url}${endpoints.FETCH_COUNTRIES}`).then((res) => res.data);
156192
},

assets/src/js/v3/shared/utils/endpoints.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ const endpoints = {
184184

185185
// Quiz Attempts
186186
START_QUIZ: 'tutor_start_quiz',
187+
UPDATE_PROFILE_NOTIFICATION: 'tutor_save_notification_preference',
187188
} as const;
188189

189190
export default endpoints;
Lines changed: 131 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Tutor dashboard profile settings
2-
32
@use '@Core/scss/tokens' as *;
43
@use '@Core/scss/mixins' as *;
54

@@ -10,131 +9,141 @@ body:has(#wpadminbar) {
109
}
1110

1211
.tutor-profile-settings-section {
13-
background: $tutor-surface-base;
14-
display: flex;
15-
flex-direction: column;
16-
position: relative;
17-
.tutor-tabs-vertical {
18-
display: block;
19-
}
20-
21-
@include tutor-breakpoint-down(md) {
22-
.tutor-dashboard-container {
23-
.tutor-tabs-tab {
24-
gap: $tutor-spacing-6;
25-
&:hover:not(:disabled):not(.tutor-tabs-tab-active) {
26-
background: transparent;
27-
}
28-
}
29-
30-
.tutor-profile-settings-tab {
31-
background: $tutor-surface-base;
32-
height: 100dvh;
33-
overflow-y: visible;
34-
flex-direction: column;
35-
width: 100%;
36-
flex-direction: column;
37-
gap: $tutor-spacing-6;
38-
background: transparent;
39-
border: 0px;
40-
overflow: unset;
41-
}
42-
43-
.tutor-profile-settings-tab button {
44-
padding: 0px 0px;
45-
}
46-
47-
.tutor-icon {
48-
background: $tutor-surface-l1;
49-
color: $tutor-text-secondary;
50-
width: 48px;
51-
height: 48px;
52-
border-radius: $tutor-radius-md;
53-
border: 1px solid $tutor-border-idle;
54-
}
55-
56-
.tutor-tabs-tab-active {
57-
color: $tutor-text-brand;
58-
background-color: transparent;
59-
}
60-
}
61-
.tutor-profile-settings-tab-content {
62-
background: $tutor-surface-base;
63-
position: absolute;
64-
top: 60px;
65-
height: 100dvh;
66-
display: none;
67-
overflow-y: scroll;
68-
padding: $tutor-spacing-6;
69-
70-
&.tutor-profile-tab-activated {
71-
left: 0px;
72-
display: block;
73-
}
74-
}
75-
}
12+
background: $tutor-surface-base;
13+
display: flex;
14+
flex-direction: column;
15+
position: relative;
16+
17+
.tutor-tabs-vertical {
18+
display: block;
19+
}
20+
21+
@include tutor-breakpoint-down(md) {
22+
.tutor-dashboard-container {
23+
.tutor-tabs-tab {
24+
gap: $tutor-spacing-6;
25+
26+
&:hover:not(:disabled):not(.tutor-tabs-tab-active) {
27+
background: transparent;
28+
}
29+
}
30+
31+
.tutor-profile-settings-tab {
32+
background: $tutor-surface-base;
33+
height: 100dvh;
34+
overflow-y: visible;
35+
flex-direction: column;
36+
width: 100%;
37+
flex-direction: column;
38+
gap: $tutor-spacing-6;
39+
background: transparent;
40+
border: 0px;
41+
overflow: unset;
42+
}
43+
44+
.tutor-profile-settings-tab button {
45+
padding: 0px 0px;
46+
}
47+
48+
.tutor-icon {
49+
background: $tutor-surface-l1;
50+
color: $tutor-text-secondary;
51+
width: 48px;
52+
height: 48px;
53+
border-radius: $tutor-radius-md;
54+
border: 1px solid $tutor-border-idle;
55+
}
56+
57+
.tutor-tabs-tab-active {
58+
color: $tutor-text-brand;
59+
background-color: transparent;
60+
}
61+
}
62+
63+
.tutor-profile-settings-tab-content {
64+
background: $tutor-surface-base;
65+
position: absolute;
66+
top: 60px;
67+
height: 100dvh;
68+
display: none;
69+
overflow-y: scroll;
70+
padding: $tutor-spacing-6;
71+
72+
&.tutor-profile-tab-activated {
73+
left: 0px;
74+
display: block;
75+
}
76+
}
77+
}
7678
}
7779

7880
.tutor-profile-settings-tab {
79-
border: 1px solid $tutor-border-idle;
80-
padding: $tutor-spacing-5;
81-
border-radius: $tutor-radius-2xl;
82-
background-color: $tutor-surface-l1;
83-
height: min-content;
84-
position: sticky;
85-
top: calc(57px + 32px);
86-
button {
87-
font-weight: $tutor-font-weight-regular;
88-
height: unset;
89-
padding: $tutor-spacing-4 $tutor-spacing-7;
90-
}
81+
border: 1px solid $tutor-border-idle;
82+
padding: $tutor-spacing-5;
83+
border-radius: $tutor-radius-2xl;
84+
background-color: $tutor-surface-l1;
85+
height: min-content;
86+
position: sticky;
87+
top: calc(57px + 32px);
88+
89+
button {
90+
font-weight: $tutor-font-weight-regular;
91+
height: unset;
92+
padding: $tutor-spacing-4 $tutor-spacing-7;
93+
}
9194
}
9295

9396
// profile notification section
9497
.tutor-profile-notification {
95-
.tutor-profile-notification-card {
96-
background-color: $tutor-surface-l1;
97-
border: 1px solid $tutor-border-idle;
98-
overflow: hidden;
99-
&:hover {
100-
.tutor-profile-notification-toggle {
101-
visibility: visible;
102-
}
103-
}
104-
}
105-
106-
.tutor-profile-notification-content {
107-
border-top: 1px solid $tutor-border-idle;
108-
}
109-
110-
.tutor-profile-notification-toggle {
111-
display: flex;
112-
align-items: center;
113-
cursor: pointer;
114-
visibility: hidden;
115-
&:hover {
116-
color: $tutor-text-primary;
117-
}
118-
svg {
119-
@include tutor-transition(transform);
120-
path {
121-
transform: translate(0px, 2px);
122-
}
123-
}
124-
&.is-expanded {
125-
visibility: visible;
126-
svg {
127-
color: $tutor-text-primary;
128-
transform: rotate(90deg);
129-
}
130-
}
131-
}
132-
133-
.tutor-input-field {
134-
margin-bottom: 0px;
135-
}
136-
137-
.tutor-profile-notification-content {
138-
border-top: 1px solid $tutor-border-idle;
139-
}
140-
}
98+
.tutor-profile-notification-card {
99+
background-color: $tutor-surface-l1;
100+
border: 1px solid $tutor-border-idle;
101+
overflow: hidden;
102+
103+
&:hover {
104+
.tutor-profile-notification-toggle {
105+
visibility: visible;
106+
}
107+
}
108+
}
109+
110+
.tutor-profile-notification-content {
111+
border-top: 1px solid $tutor-border-idle;
112+
}
113+
114+
.tutor-profile-notification-toggle {
115+
display: flex;
116+
align-items: center;
117+
cursor: pointer;
118+
visibility: hidden;
119+
120+
&:not(.is-disabled):hover {
121+
color: $tutor-text-primary;
122+
}
123+
124+
svg {
125+
@include tutor-transition(transform);
126+
127+
path {
128+
transform: translate(0px, 2px);
129+
}
130+
}
131+
132+
&.is-expanded {
133+
visibility: visible;
134+
135+
svg {
136+
color: $tutor-text-primary;
137+
transform: rotate(90deg);
138+
}
139+
}
140+
}
141+
142+
.tutor-input-field {
143+
margin-bottom: 0px;
144+
}
145+
146+
.tutor-profile-notification-content {
147+
border-top: 1px solid $tutor-border-idle;
148+
}
149+
}

classes/Template.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -536,12 +536,6 @@ public static function make_learning_area_sub_page_nav_items( $base_url = '' ):
536536
}
537537

538538
$menu_items = array(
539-
'resources' => array(
540-
'title' => __( 'Resources', 'tutor' ),
541-
'icon' => Icon::RESOURCES,
542-
'url' => UrlHelper::add_query_params( $base_url, array( 'subpage' => 'resources' ) ),
543-
'template' => tutor_get_template( 'learning-area.subpages.resources' ),
544-
),
545539
'qna' => array(
546540
'title' => __( 'Q&A', 'tutor' ),
547541
'icon' => Icon::QA,

templates/dashboard/account/reviews.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use TUTOR\Icon;
1313
use TUTOR\Input;
14+
use TUTOR\User;
1415
use Tutor\Components\Button;
1516
use Tutor\Components\ConfirmationModal;
1617
use Tutor\Components\EmptyState;
@@ -25,11 +26,10 @@
2526
$current_page = max( 1, Input::get( 'current_page', 0, Input::TYPE_INT ) );
2627
$offset = ( $current_page - 1 ) * $item_per_page;
2728

28-
$all_reviews = tutor_utils()->get_reviews_by_user( 0, $offset, $item_per_page, true );
29-
$review_count = $all_reviews->count;
30-
$reviews = $all_reviews->results;
31-
$is_instructor = tutor_utils()->is_instructor( 0, true );
32-
$is_editable = $is_instructor ? false : true;
29+
$all_reviews = tutor_utils()->get_reviews_by_user( 0, $offset, $item_per_page, true );
30+
$review_count = $all_reviews->count;
31+
$reviews = $all_reviews->results;
32+
$is_editable = User::is_student_view();
3333

3434
foreach ( $reviews as $review ) {
3535
$review->is_editable = $is_editable;

0 commit comments

Comments
 (0)