Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 .husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pnpm exec tsc
2 changes: 1 addition & 1 deletion .lintstagedrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"*.{ts,tsx}": ["pnpm exec eslint --fix"],
"*.{ts,tsx}": ["pnpm exec eslint --fix", "bash -c 'pnpm exec tsc --noEmit'"],
"*.{ts,tsx,jsonc,md}": ["pnpm exec prettier --write"]
}
2 changes: 1 addition & 1 deletion .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Global, css } from '@emotion/react';
import { withThemeFromJSXProvider } from '@storybook/addon-themes';
import type { Preview } from '@storybook/react';
import { type Preview } from 'storybook-react-rsbuild';

import { tutorConfig } from '@TutorShared/config/config';
import { typography } from '@TutorShared/config/typography';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ const questionMatching = (
}

if (targetDropZone) {
const dropZoneEl = targetDropZone.element;
const dropZoneEl = targetDropZone.element as HTMLElement;
const sourceId = operation.source.id;

if (!dropZoneEl) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import SearchField from './SearchField';

interface CategoryListTableProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
form: UseFormReturn<Coupon, any, undefined>;
form: UseFormReturn<Coupon, any, any>;
}

const CategoryListTable = ({ form }: CategoryListTableProps) => {
Expand Down Expand Up @@ -83,7 +83,7 @@ const CategoryListTable = ({ form }: CategoryListTableProps) => {
</div>
);
},
width: 720,
width: '720px',
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import SearchField from './SearchField';

interface CourseListTableProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
form: UseFormReturn<Coupon, any, undefined>;
form: UseFormReturn<Coupon, any, any>;
type: 'bundles' | 'courses';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import SearchField from './SearchField';

interface MembershipPlanListTableProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
form: UseFormReturn<Coupon, any, undefined>;
form: UseFormReturn<Coupon, any, any>;
}

const MembershipPlanListTable = ({ form }: MembershipPlanListTableProps) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import MembershipPlanListTable from './MembershipPlanListTable';
interface CouponSelectItemModalProps extends ModalProps {
closeModal: (props?: { action: 'CONFIRM' | 'CLOSE' }) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
form: UseFormReturn<Coupon, any, undefined>;
form: UseFormReturn<Coupon, any, any>;
type: 'bundles' | 'courses' | 'categories' | 'membershipPlans';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const ZoomMeetingCard = ({ data, meetingHost, topicId }: ZoomMeetingCardProps) =

const handleZoomMeetingDelete = async () => {
const response = await deleteZoomMeetingMutation.mutateAsync(ID);
if (response.success) {
if (response.status_code === 200) {
setIsDeletePopoverOpen(false);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const QuizModal = ({
hide_quiz_time_display: false,
limit_attempts_allowed: false,
limit_questions_to_answer: false,
attempts_allowed: defaultQuizAttemptsAllowed,
attempts_allowed: Number(defaultQuizAttemptsAllowed),
passing_grade: 80,
max_questions_for_answer: contentType === 'tutor_h5p_quiz' ? 0 : 10,
quiz_auto_start: false,
Expand All @@ -100,7 +100,7 @@ const QuizModal = ({
enable_pagination: false,
pagination_type: 'shape',
enable_answer_reveal: false,
answers_reveal_duration: 5,
answers_reveal_duration: '5',
hide_previous_button: false,
hide_question_number_overview: false,
short_answer_characters_limit: 200,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const OptionWebhookUrl = ({

const handleCopyClick = async () => {
try {
await copyToClipboard(field.value);
await copyToClipboard(field?.value || '');
showToast({
type: 'success',
message: __('Copied to clipboard', 'tutor'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ function EuropeanUnionTax() {
}}
/>
<Button
variant="text"
isIconOnly
aria-label={__('Delete', 'tutor')}
icon={<SVGIcon name="delete" style={styles.deleteIcon} />}
onClick={() => {
const updatedRates = rates.map((rate) => {
Expand All @@ -95,7 +96,7 @@ function EuropeanUnionTax() {
</>
);
},
width: 120,
width: '120px',
},
];

Expand Down
10 changes: 6 additions & 4 deletions assets/src/js/v3/entries/tax-settings/components/TaxRates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ export default function TaxRates() {
}}
/>
<Button
variant="text"
isIconOnly
aria-label={__('Delete', 'tutor')}
buttonCss={styles.deleteIcon}
icon={<SVGIcon height={24} width={24} name="delete" />}
onClick={() => {
Expand Down Expand Up @@ -233,7 +234,8 @@ export default function TaxRates() {
/>

<Button
variant="text"
isIconOnly
aria-label={__('Delete', 'tutor')}
buttonCss={styles.deleteIcon}
icon={<SVGIcon height={24} width={24} name="delete" />}
onClick={() => {
Expand Down Expand Up @@ -262,7 +264,7 @@ export default function TaxRates() {
</div>
);
},
width: activeCountry ? 180 : 100,
width: activeCountry ? '180px' : '100px',
},
];

Expand All @@ -272,7 +274,7 @@ export default function TaxRates() {
Cell: (item) => {
return <MoreOptions data={item} />;
},
width: 32,
width: '32px',
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,11 @@ const FormMultiLevelInput = ({
key={option.id}
disabled={disabled}
option={option}
value={field.value}
value={field.value || []}
isLastChild={index === treeOptions.length - 1}
onChange={(id) => {
field.onChange(
produce(field.value, (draft) => {
produce(field.value || [], (draft) => {
if (Array.isArray(draft)) {
return draft.includes(id) ? draft.filter((item) => item !== id) : [...draft, id];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const FormImageInput = ({
<div>
<ImageInput
size={size}
value={fieldValue}
value={fieldValue ?? null}
uploadHandler={handleMediaButtonClick}
clearHandler={clearHandler}
buttonText={buttonText}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const FormRangeSliderField = ({
hasBorder = false,
}: FormRangeSliderFieldProps) => {
const ref = useRef<HTMLInputElement>(null);
const [value, setValue] = useState<number>(field.value);
const [value, setValue] = useState<number>(field.value ?? 0);
const sliderRef = useRef<HTMLDivElement>(null);
const thumbRef = useRef<HTMLDivElement>(null);
const debounceValue = useDebounce(value);
Expand Down
14 changes: 7 additions & 7 deletions assets/src/js/v3/shared/components/fields/FormVideoInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ const FormVideoInput = ({
source_video_id: file.id.toString(),
source_html5: file.url,
};
field.onChange(updateFieldValue(field.value, updateData));
onChange?.(updateFieldValue(field.value, updateData));
field.onChange(updateFieldValue(field.value ?? null, updateData));
onChange?.(updateFieldValue(field.value ?? null, updateData));

try {
setIsThumbnailLoading(true);
Expand Down Expand Up @@ -256,8 +256,8 @@ const FormVideoInput = ({
poster: file.id.toString(),
poster_url: file.url,
};
field.onChange(updateFieldValue(field.value, updateData));
onChange?.(updateFieldValue(field.value, updateData));
field.onChange(updateFieldValue(field.value ?? null, updateData));
onChange?.(updateFieldValue(field.value ?? null, updateData));
},
initialFiles: field.value?.poster
? { id: Number(field.value.poster), url: field.value.poster_url, title: '' }
Expand Down Expand Up @@ -401,7 +401,7 @@ const FormVideoInput = ({
type === 'video'
? { source: '', source_video_id: '', poster: '', poster_url: '' }
: { poster: '', poster_url: '' };
const updatedValue = updateFieldValue(fieldValue, updateData);
const updatedValue = updateFieldValue(fieldValue ?? null, updateData);
if (type === 'video') {
resetVideoSelection();
} else {
Expand Down Expand Up @@ -438,8 +438,8 @@ const FormVideoInput = ({
[`source_${source}`]: url,
};

field.onChange(updateFieldValue(fieldValue, updatedValue));
onChange?.(updateFieldValue(fieldValue, updatedValue));
field.onChange(updateFieldValue(fieldValue ?? null, updatedValue));
onChange?.(updateFieldValue(fieldValue ?? null, updatedValue));
setIsOpen(false);

const [duration, thumbnail] = await Promise.all([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,23 @@ const FormImageAnswering = ({
validationError,
setValidationError,
}: FormImageAnsweringProps) => {
const inputValue = field.value ?? {
answer_id: nanoid(),
answer_title: '',
is_correct: '0',
belongs_question_id: questionId,
belongs_question_type: 'image_answering',
};
const inputValue =
field.value ??
({
answer_id: nanoid(),
answer_title: '',
is_correct: '0',
belongs_question_id: questionId,
belongs_question_type: 'image_answering',
image_id: '',
} as QuizQuestionOption);
const inputRef = useRef<HTMLInputElement>(null);

const [isEditing, setIsEditing] = useState(!inputValue.answer_title && !inputValue.image_id && !inputValue.image_url);
const [previousValue, setPreviousValue] = useState<QuizQuestionOption>(inputValue);

const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
id: field.value.answer_id || 0,
id: field?.value?.answer_id || 0,
animateLayoutChanges,
});
const { openMediaLibrary, resetFiles } = useWPMedia({
Expand All @@ -91,7 +94,7 @@ const FormImageAnswering = ({
});
}
},
initialFiles: field.value.image_id
initialFiles: field?.value?.image_id
? {
id: Number(inputValue.image_id),
url: inputValue.image_url || '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ const FormMatching = ({
validationError,
setValidationError,
}: FormMatchingProps) => {
const inputValue = field.value ?? {
answer_id: '',
answer_title: '',
answer_two_gap_match: '',
is_correct: '0',
belongs_question_id: questionId,
belongs_question_type: 'matching',
};
const inputValue =
field.value ??
({
answer_id: '',
answer_title: '',
answer_two_gap_match: '',
is_correct: '0',
belongs_question_id: questionId,
belongs_question_type: 'matching',
} as QuizQuestionOption);
const inputRef = useRef<HTMLInputElement>(null);

const [isEditing, setIsEditing] = useState(
Expand All @@ -77,7 +79,7 @@ const FormMatching = ({
const [previousValue, setPreviousValue] = useState<QuizQuestionOption>(inputValue);

const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
id: field.value.answer_id || 0,
id: field.value?.answer_id || 0,
animateLayoutChanges,
});
const { openMediaLibrary, resetFiles } = useWPMedia({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,15 @@ const FormMultipleChoiceAndOrdering = ({
validationError,
setValidationError,
}: FormMultipleChoiceAndOrderingProps) => {
const inputValue = field.value ?? {
answer_id: nanoid(),
answer_title: '',
is_correct: '0',
belongs_question_id: questionId,
belongs_question_type: 'multiple_choice',
};
const inputValue =
field.value ??
({
answer_id: nanoid(),
answer_title: '',
is_correct: '0',
belongs_question_id: questionId,
belongs_question_type: 'multiple_choice',
} as QuizQuestionOption);
const inputRef = useRef<HTMLTextAreaElement>(null);

const [isEditing, setIsEditing] = useState(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const CategoryListTable = ({ form }: CategoryListTableProps) => {
</div>
);
},
width: 720,
width: '720px',
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export default function SubscriptionItem() {
label={__('Billing Cycles', __TUTOR_TEXT_DOMAIN__)}
placeholder={__('Select or type times to renewing the plan', __TUTOR_TEXT_DOMAIN__)}
content={
!billingCyclesCustomPresets.includes(controllerProps.field.value) &&
!billingCyclesCustomPresets.includes(controllerProps.field.value ?? '') &&
__('Times', __TUTOR_TEXT_DOMAIN__)
}
contentPosition="right"
Expand Down
3 changes: 1 addition & 2 deletions assets/src/js/v3/shared/hooks/useFormWithGlobalError.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from 'react';
import { type UseFormReturn, useForm } from 'react-hook-form';
import type { FieldValues, UseFormProps } from 'react-hook-form/dist/types';
import { type FieldValues, type UseFormProps, type UseFormReturn, useForm } from 'react-hook-form';

export type FormWithGlobalErrorType<T extends FieldValues> = UseFormReturn<T> & {
setSubmitError: (error: string | undefined) => void;
Expand Down
2 changes: 1 addition & 1 deletion assets/src/js/v3/shared/hooks/useResetForm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback } from 'react';
import type { FieldValues } from 'react-hook-form/dist/types';
import { type FieldValues } from 'react-hook-form';

import type { FormWithGlobalErrorType } from './useFormWithGlobalError';

Expand Down
8 changes: 4 additions & 4 deletions assets/src/js/v3/shared/utils/local-storage.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import type { LocalStorage } from '@TutorShared/config/constants';
import { type LocalStorageKeys } from '@TutorShared/config/constants';

export const getStorageItem = (key: LocalStorage) => {
export const getStorageItem = (key: LocalStorageKeys) => {
if (typeof window !== 'undefined') {
return window.localStorage.getItem(key) || null;
}

return null;
};

export const setStorageItem = (key: LocalStorage, value: string) => {
export const setStorageItem = (key: LocalStorageKeys, value: string) => {
if (typeof window !== 'undefined') {
window.localStorage.setItem(key, value);
}
};

export const removeStorageItem = (key: LocalStorage) => {
export const removeStorageItem = (key: LocalStorageKeys) => {
if (typeof window !== 'undefined') {
window.localStorage.removeItem(key);
}
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/backend/announcements.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { backendUrls } from '../../config/page-urls';
import { backendUrls } from '@Cypress/config/page-urls';

describe('Tutor Admin Announcements', () => {
beforeEach(() => {
Expand Down
Loading
Loading