Skip to content

Commit

Permalink
Add 'Coming Soon' feature with thumbnail upload and curriculum previe…
Browse files Browse the repository at this point in the history
…w options
  • Loading branch information
b-l-i-n-d committed Jan 24, 2025
1 parent a1efec0 commit f04d85f
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@ import { useEffect, useState } from 'react';
import { Controller, useFormContext, useWatch } from 'react-hook-form';

import Button from '@TutorShared/atoms/Button';
import ImageInput from '@TutorShared/atoms/ImageInput';
import SVGIcon from '@TutorShared/atoms/SVGIcon';

import FormCheckbox from '@TutorShared/components/fields/FormCheckbox';
import FormDateInput from '@TutorShared/components/fields/FormDateInput';
import FormImageInput from '@TutorShared/components/fields/FormImageInput';
import FormSwitch from '@TutorShared/components/fields/FormSwitch';
import FormTimeInput from '@TutorShared/components/fields/FormTimeInput';

import type { CourseFormData } from '@CourseBuilderServices/course';
import { tutorConfig } from '@TutorShared/config/config';
import { DateFormats } from '@TutorShared/config/constants';
import { borderRadius, colorTokens, spacing } from '@TutorShared/config/styles';
import { typography } from '@TutorShared/config/typography';
import Show from '@TutorShared/controls/Show';
import type { CourseFormData } from '@CourseBuilderServices/course';
import { styleUtils } from '@TutorShared/utils/style-utils';
import { noop } from '@TutorShared/utils/util';
import { invalidDateRule, invalidTimeRule } from '@TutorShared/utils/validation';

const ScheduleOptions = () => {
Expand All @@ -26,6 +31,7 @@ const ScheduleOptions = () => {
const scheduleTime = useWatch({ name: 'schedule_time' }) ?? format(addHours(new Date(), 1), DateFormats.hoursMinutes);
const isScheduleEnabled = useWatch({ name: 'isScheduleEnabled' }) ?? false;
const showForm = useWatch({ name: 'showScheduleForm' }) ?? false;
const isComingSoonEnabled = useWatch({ name: 'enable_coming_soon' }) ?? false;

const [previousPostDate, setPreviousPostDate] = useState(
scheduleDate && scheduleTime && isValid(new Date(`${scheduleDate} ${scheduleTime}`))
Expand Down Expand Up @@ -69,11 +75,11 @@ const ScheduleOptions = () => {
);
};

// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
useEffect(() => {
if (isScheduleEnabled && showForm) {
form.setFocus('schedule_date');
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [showForm, isScheduleEnabled]);

return (
Expand Down Expand Up @@ -146,6 +152,45 @@ const ScheduleOptions = () => {
)}
/>
</div>

<Controller
name="enable_coming_soon"
control={form.control}
render={(controllerProps) => (
<FormCheckbox
{...controllerProps}
label={__('Show coming soon in course list & details page', 'tutor')}
labelCss={styles.checkboxStartAlign}
/>
)}
/>

<Show when={isComingSoonEnabled}>
<Controller
name="coming_soon_thumbnail"
control={form.control}
render={(controllerProps) => (
<FormImageInput
{...controllerProps}
label={__('Coming Soon Thumbnail', 'tutor')}
buttonText={__('Upload Thumbnail', 'tutor')}
infoText={sprintf(
__('JPEG, PNG, GIF, and WebP formats, up to %s', 'tutor'),
tutorConfig.max_upload_size,
)}
/>
)}
/>

<Controller
name="enable_curriculum_preview"
control={form.control}
render={(controllerProps) => (
<FormCheckbox {...controllerProps} label={__('Preview Course Curriculum', 'tutor')} />
)}
/>
</Show>

<div css={styles.scheduleButtonsWrapper}>
<Button
variant="tertiary"
Expand Down Expand Up @@ -195,6 +240,8 @@ const ScheduleOptions = () => {
<div css={styles.scheduleInfo}>
{sprintf(__('%s at %s', 'tutor'), format(parseISO(scheduleDate), DateFormats.monthDayYear), scheduleTime)}
</div>

<ImageInput value={form.watch('coming_soon_thumbnail')} uploadHandler={noop} clearHandler={noop} disabled />
</Show>
</div>
)}
Expand All @@ -213,6 +260,8 @@ const styles = {
background-color: ${colorTokens.bg.white};
`,
formWrapper: css`
${styleUtils.display.flex('column')};
gap: ${spacing[8]};
margin-top: ${spacing[16]};
`,
scheduleButtonsWrapper: css`
Expand Down Expand Up @@ -255,4 +304,10 @@ const styles = {
border-radius: ${borderRadius[4]};
text-align: center;
`,
checkboxStartAlign: css`
span:first-of-type {
align-self: flex-start;
margin-top: ${spacing[4]};
}
`,
};
37 changes: 28 additions & 9 deletions assets/react/v3/entries/course-builder/services/course.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { CourseVideo } from '@TutorShared/components/fields/FormVideoInput'
import { tutorConfig } from '@TutorShared/config/config';
import { Addons, DateFormats } from '@TutorShared/config/constants';
import { type WPMedia } from '@TutorShared/hooks/useWpMedia';
import { Course } from '@TutorShared/services/course';
import { type Course } from '@TutorShared/services/course';
import type { Tag } from '@TutorShared/services/tags';
import type { InstructorListResponse, User } from '@TutorShared/services/users';
import { wpAjaxInstance } from '@TutorShared/utils/api';
Expand Down Expand Up @@ -75,6 +75,9 @@ export interface CourseFormData {
showScheduleForm: boolean;
schedule_date: string;
schedule_time: string;
enable_coming_soon: boolean;
coming_soon_thumbnail: WPMedia | null;
enable_curriculum_preview: boolean; // Only when coming-soon is enabled
}

export const courseDefaultData: CourseFormData = {
Expand Down Expand Up @@ -141,6 +144,9 @@ export const courseDefaultData: CourseFormData = {
showScheduleForm: false,
schedule_date: '',
schedule_time: '',
enable_coming_soon: false,
coming_soon_thumbnail: null,
enable_curriculum_preview: false,
};

export interface CoursePayload {
Expand Down Expand Up @@ -192,6 +198,11 @@ export interface CoursePayload {
'video[source_embedded]'?: string;
tutor_attachments: number[];
bp_attached_group_ids: string[];

// when course is scheduled
enable_coming_soon?: boolean;
coming_soon_thumbnail_id?: number;
enable_curriculum_preview?: boolean;
}

export type CourseBuilderSteps = 'basic' | 'curriculum' | 'additional';
Expand Down Expand Up @@ -304,15 +315,13 @@ export interface CourseDetailsResponse {
course_requirements: string;
course_target_audience: string;
course_material_includes: string;
course_sale_price: string;
course_settings: {
maximum_students: number;
content_drip_type: ContentDripType;
enable_content_drip: number;
enrollment_expiry: number;
enable_tutor_bp: 1 | 0;
};
step_completion_status: Record<CourseBuilderSteps, boolean>;
course_pricing: {
price: string;
product_id: string;
Expand All @@ -330,18 +339,16 @@ export interface CourseDetailsResponse {
zoom_users: {
[key: string]: string;
};
zoom_timezones: {
[key: string]: string;
};
zoom_meetings: ZoomMeeting[];
google_meet_timezones: {
[key: string]: string;
};
google_meet_meetings: GoogleMeet[];
bp_attached_groups: string[];
editor_used: Editor;
editors: Editor[];
total_enrolled_student: number;
enable_coming_soon: boolean;
coming_soon_thumbnail: string;
coming_soon_thumbnail_id: number;
enable_curriculum_preview: boolean;
}

export type MeetingType = 'zoom' | 'google_meet';
Expand Down Expand Up @@ -511,6 +518,11 @@ export const convertCourseDataToPayload = (data: CourseFormData): CoursePayload
: {}),
tutor_attachments: (data.course_attachments || []).map((item) => item.id) ?? [],
bp_attached_group_ids: data.bp_attached_group_ids,
...(isBefore(new Date(), new Date(data.post_date)) && {
enable_coming_soon: data.enable_coming_soon,
coming_soon_thumbnail_id: data.coming_soon_thumbnail?.id ?? -1,
enable_curriculum_preview: data.enable_curriculum_preview,
}),
};
};

Expand Down Expand Up @@ -618,6 +630,13 @@ export const convertCourseDataToFormData = (courseDetails: CourseDetailsResponse
schedule_time: !isBefore(parseISO(courseDetails.post_date), new Date())
? format(parseISO(courseDetails.post_date), DateFormats.hoursMinutes)
: '',
enable_coming_soon: courseDetails.enable_coming_soon ?? false,
coming_soon_thumbnail: {
id: Number(courseDetails.coming_soon_thumbnail_id),
title: '',
url: courseDetails.coming_soon_thumbnail,
},
enable_curriculum_preview: courseDetails.enable_curriculum_preview ?? false,
};
};

Expand Down

0 comments on commit f04d85f

Please sign in to comment.