-
Notifications
You must be signed in to change notification settings - Fork 82
Learning Qna #2320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 4.0.0-dev
Are you sure you want to change the base?
Learning Qna #2320
Conversation
- Create new qna.ts page component with Q&A mutation handlers - Add initializeQnA function to register Q&A component with Alpine.js - Integrate Q&A page initialization into learning area router - Implement createQnA, replyQna, and deleteQnA mutation methods - Add success/error toast notifications for Q&A operations - Update package-lock.json dependencies - Enable Q&A functionality in learning area templates
| /** | ||
| * Q&A Page Component | ||
| * Handles Q&A question creation in learning area | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is unnecessary.
| window.location.reload(); | ||
| }, | ||
| onError: (error: Error) => { | ||
| window.TutorCore.toast.error(error.message || __('Failed to save question', 'tutor')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use convertToErrorMessage
| window.TutorCore.toast.error(error.message || __('Failed to save question', 'tutor')); | |
| window.TutorCore.toast.error(convertToErrorMessage(error)); |
| window.location.reload(); | ||
| }, | ||
| onError: (error: Error) => { | ||
| window.TutorCore.toast.error(error.message || __('Failed to save reply', 'tutor')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
| }, | ||
| }); | ||
|
|
||
| // Q&A delete mutation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this comment as this is self-explanatory.
| } | ||
| }, | ||
| onError: (error: Error) => { | ||
| window.TutorCore.toast.error(error.message || __('Failed to delete Q&A', 'tutor')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use convertToErrorMessage
| window.TutorCore.toast.error(error.message || __('Failed to delete Q&A', 'tutor')); | |
| window.TutorCore.toast.error(convertToErrorMessage(error)); |
| </div> | ||
| <?php if ( $current_user_id == $answer->user_id || current_user_can( 'manage_tutor' ) ) : ?> | ||
| <div x-data="tutorPopover({ placement: 'bottom-end', offset: 4 })" class="tutor-ml-auto"> | ||
| <button class="tutor-btn tutor-btn-ghost tutor-btn-icon tutor-btn-x-small" x-ref="trigger" @click="toggle()"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use php Button component
| </div> | ||
| </div> | ||
| <?php if ( $current_user_id == $answer->user_id || current_user_can( 'manage_tutor' ) ) : ?> | ||
| <div x-data="tutorPopover({ placement: 'bottom-end', offset: 4 })" class="tutor-ml-auto"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this can be done with php Popover component, then please use that.
| ?> | ||
| <div class="tutor-input-field"> | ||
| <div class="tutor-input-wrapper"> | ||
| <input |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use php component
| <form | ||
| class="tutor-discussion-form tutor-p-6 tutor-border-b tutor-qna-form" | ||
| x-data="{ ...tutorForm({ id: '<?php echo esc_attr( $tutor_course_id ); ?>' }), focused : false }" | ||
| @submit.prevent="handleSubmit((data) => createQnaMutation?.mutate({...data, course_id: <?php echo esc_html( $tutor_course_id ); ?> }))($event)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass course_id as a default value.
| $content = strlen( $content ) > 100 ? substr( $content, 0, 100 ) . '...' : $content; | ||
| ?> | ||
| <div class="tutor-discussion-card" @click="window.location.href = '<?php echo esc_url( $question_url ); ?>'" style="cursor: pointer;"> | ||
| <div class="tutor-avatar tutor-avatar-32"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use php Avatar component
- Import and use convertToErrorMessage utility for consistent error formatting
| * @link https://themeum.com | ||
| * @since 4.0.0 | ||
| */ | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent direct access
defined( 'ABSPATH' ) || exit;|
|
||
| // Get course ID and question ID. | ||
| global $tutor_course_id; | ||
| $question_id = Input::get( 'question_id', null, Input::TYPE_INT ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use default 0
| $order_by = Input::get( 'order', 'DESC' ); | ||
|
|
||
| // Get question data. | ||
| $question = tutor_utils()->get_qa_question( (int) $question_id ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to cast. It's already int by Input::TYPE_INT
| </button> | ||
| 5 | ||
|
|
||
| <?php if ( is_array( $answers ) && count( $answers ) ) : ?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this is_array( $answers ) && count( $answers ) use
tutor_utils()->count( $answers );| * @link https://themeum.com | ||
| * @since 4.0.0 | ||
| */ | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent direct access
| ); | ||
| Sorting::make() | ||
| ->order( Input::get( 'order', 'DESC' ) ) | ||
| ->label_asc( __( 'Newest First', 'tutor' ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default value is same as you passed. No need to call label_asc and label_desc
| <?php | ||
| Pagination::make() | ||
| ->current( $current_page ) | ||
| ->total( (int) $total_items ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to cast int
| <?php | ||
| Sorting::make() | ||
| ->order( Input::get( 'order', 'DESC' ) ) | ||
| ->label_asc( __( 'Newest First', 'tutor' ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default value is same as you passed. No need to call label_asc and label_desc
| position: fixed; | ||
| height: calc(100vh - 62px); | ||
| top: 62px; | ||
| position: absolute; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this.
templates/learning-area/index.php
Outdated
| if ( $subpage ) { | ||
| $subpage_template = tutor_get_template( 'learning-area.subpages.' . $subpage ); | ||
| if ( file_exists( $subpage_template ) ) { | ||
| if ( $question_id ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be managed inside qna.php template.
- Refactor learning-area index template to handle question_id routing in qna-single subpage - Update Sorting component usage by removing custom labels - Improve answer count validation using tutor_utils()->count() helper - Add SearchFilter component import and implement search functionality in Q&A page - Add ABSPATH check for security in qna-single template - Consolidate question_id routing logic into qna-single subpage for better separation of concerns - Add Avatar component import to qna template
- Add Popover component import to qna-single.php - Replace manual x-data popover implementation with Popover::make() component for question actions menu - Replace manual x-data popover implementation with Popover::make() component for reply actions menu - Update SearchFilter placeholder text from 'Search items...' to 'Search questions, topics...' - Update textarea placeholder text from 'Ask a question...' to 'Asked questions...' - Fix indentation inconsistency in SearchFilter component call - Simplifies popover markup by using component abstraction instead of manual Alpine.js directives
- Add `defined( 'ABSPATH' ) || exit;` security check to both qna.php and qna-single.php templates - Replace manual form with SearchFilter component using UrlHelper for cleaner URL handling - Update form submission to use defaultValues in tutorForm configuration - Remove unnecessary hidden input loop in favor of component-based hidden_inputs parameter
No description provided.