• File: index.tsx
  • Full Path: /home/bravrvjk/itiministry.org/wp-content/plugins/give/src/EventTickets/resources/admin/components/EventFormModal/index.tsx
  • Date Modified: 02/03/2025 8:13 PM
  • File size: 5.16 KB
  • MIME-type: text/x-java
  • Charset: utf-8
import {SubmitHandler, useForm} from 'react-hook-form';
import {__} from '@wordpress/i18n';
import styles from './EventFormModal.module.scss';
import FormModal from '../FormModal';
import EventTicketsApi from '../api';

/**
 * Get the next sharp hour
 *
 * @since 3.6.0
 */
const getNextSharpHour = (hoursToAdd: number) => {
    const date = new Date();
    date.setHours(date.getHours() + hoursToAdd, 0, 0, 0);

    return date;
};

/**
 * Format a given date to be used in datetime inputs
 *
 * @since 3.6.0
 */
const getDateString = (date: Date) => {
    const offsetInMilliseconds = date.getTimezoneOffset() * 60 * 1000;
    const dateWithOffset = new Date(date.getTime() - offsetInMilliseconds);

    return removeTimezoneFromDateISOString(dateWithOffset.toISOString());
};

/**
 * Remove timezone from date string
 *
 * @since 3.6.0
 */
const removeTimezoneFromDateISOString = (date: string) => {
    return date.slice(0, -5);
};

/**
 * Event Form Modal component
 *
 * @since 3.20.0 Added placeholder to event description field
 * @since 3.6.0
 */
export default function EventFormModal({isOpen, handleClose, apiSettings, title, event}: EventModalProps) {
    const API = new EventTicketsApi(apiSettings);

    const {
        register,
        handleSubmit,
        formState: {errors, isDirty},
    } = useForm<Inputs>({
        defaultValues: {
            title: event?.title ?? '',
            description: event?.description ?? '',
            startDateTime: getDateString(
                event?.startDateTime?.date ? new Date(event?.startDateTime?.date) : getNextSharpHour(1)
            ),
            endDateTime: getDateString(
                event?.endDateTime?.date ? new Date(event?.endDateTime?.date) : getNextSharpHour(2)
            ),
        },
    });

    const onSubmit: SubmitHandler<Inputs> = async (inputs) => {
        try {
            inputs.startDateTime = getDateString(new Date(inputs.startDateTime));
            inputs.endDateTime = getDateString(new Date(inputs.endDateTime));

            const endpoint = event?.id ? `/event/${event.id}` : '';
            const response = await API.fetchWithArgs(endpoint, inputs, 'POST');

            handleClose(response);
        } catch (error) {
            console.error('Error submitting event event', error);
        }
    };

    return (
        <FormModal
            isOpen={isOpen}
            handleClose={handleClose}
            title={title}
            handleSubmit={handleSubmit(onSubmit)}
            errors={errors}
            className={styles.eventForm}
        >
            <div className="givewp-event-tickets__form-row">
                <label htmlFor="title">{__('Event Name', 'give')}</label>
                <input
                    type="text"
                    {...register('title', {required: __('The event must have a name!', 'give')})}
                    aria-invalid={errors.title ? 'true' : 'false'}
                    placeholder={__('Enter event name', 'give')}
                />
            </div>
            <div className="givewp-event-tickets__form-row">
                <label htmlFor="description">{__('Description', 'give')}</label>
                <textarea
                    {...register('description')}
                    rows={4}
                    placeholder={__('Briefly describe the details of your event', 'give')}
                />
            </div>
            <div className="givewp-event-tickets__form-row givewp-event-tickets__form-row--half">
                <div className="givewp-event-tickets__form-column">
                    <label htmlFor="startDateTime">{__('Start date and time', 'give')}</label>
                    <input
                        type="datetime-local"
                        {...register('startDateTime', {required: __('The event must have a start date!', 'give')})}
                        aria-invalid={errors.startDateTime ? 'true' : 'false'}
                    />
                </div>
                <div className="givewp-event-tickets__form-column">
                    <label htmlFor="endDateTime">{__('End date and time', 'give')}</label>
                    <input type="datetime-local" {...register('endDateTime')} />
                </div>
            </div>

            <button
                type="submit"
                className={`button button-primary ${!isDirty ? 'disabled' : ''}`}
                aria-disabled={!isDirty}
                disabled={!isDirty}
            >
                {event?.id ? __('Save changes', 'give') : __('Save event', 'give')}
            </button>
        </FormModal>
    );
}

type Event = {
    id?: number;
    title: string;
    description: string;
    startDateTime: {
        date: string;
        timezone_type: number;
        timezone: string;
    };
    endDateTime: {
        date: string;
        timezone_type: number;
        timezone: string;
    };
    createdAt: string;
    updatedAt: string;
};

type Inputs = {
    title: string;
    description: string;
    startDateTime: string;
    endDateTime: string;
};

interface EventModalProps {
    isOpen: boolean;
    handleClose: (response?: any) => void;
    apiSettings: {
        apiRoot: string;
        apiNonce: string;
    };
    title: string;
    event?: Event;
}