Skip to content

Commit

Permalink
Merge branch 'main' into andy/ThemeTransitionSync
Browse files Browse the repository at this point in the history
  • Loading branch information
WishingWell13 authored Mar 30, 2024
2 parents f77941d + ef2a416 commit efe5000
Show file tree
Hide file tree
Showing 13 changed files with 562 additions and 14 deletions.
273 changes: 273 additions & 0 deletions src/components/admin/event/AdminPickupEvent/AdminPickupEventForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
import DetailsFormItem from '@/components/admin/DetailsFormItem';
import { Button } from '@/components/common';
import { config, showToast } from '@/lib';
import { AdminEventManager } from '@/lib/managers';
import { OrderPickupEvent } from '@/lib/types/apiRequests';
import { PublicEvent, PublicOrderPickupEvent } from '@/lib/types/apiResponses';
import { reportError } from '@/lib/utils';
import { DateTime } from 'luxon';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { SubmitHandler, useForm } from 'react-hook-form';
import { BsArrowRight } from 'react-icons/bs';
import style from './style.module.scss';

type FormValues = OrderPickupEvent;

interface IProps {
mode: 'create' | 'edit';
defaultData?: Partial<PublicOrderPickupEvent>;
token: string;
upcomingEvents: PublicEvent[];
}

const AdminPickupEventForm = ({ mode, defaultData = {}, token, upcomingEvents }: IProps) => {
const router = useRouter();

const initialValues: FormValues = {
title: defaultData.title ?? '',
start: DateTime.fromISO(defaultData?.start ?? '').toFormat("yyyy-MM-dd'T'HH:mm"),
end: DateTime.fromISO(defaultData?.end ?? '').toFormat("yyyy-MM-dd'T'HH:mm"),
description: defaultData.description ?? '',
orderLimit: defaultData.orderLimit ?? 0,
linkedEventUuid: defaultData.linkedEvent?.uuid ?? null,
};

const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm<OrderPickupEvent>({ defaultValues: initialValues });

const [loading, setLoading] = useState<boolean>(false);
const resetForm = () => reset(initialValues);

const createPickupEvent: SubmitHandler<FormValues> = async formData => {
setLoading(true);

const {
title,
start: isoStart,
end: isoEnd,
linkedEventUuid,
description,
orderLimit: rawOrderLimit,
} = formData;

const start = new Date(isoStart).toISOString();
const end = new Date(isoEnd).toISOString();
const orderLimit = parseInt(`${rawOrderLimit}`, 10);

try {
const uuid = await AdminEventManager.createPickupEvent(token, {
title,
start,
end,
description,
orderLimit,
linkedEventUuid,
});
showToast('Pickup Event created successfully!', '', [
{
text: 'Continue editing',
onClick: () => router.push(`${config.admin.store.pickupEdit}/${uuid}`),
},
]);
router.push(`${config.admin.store.pickup}/${uuid}`);
} catch (error) {
reportError('Could not create pickup event', error);
} finally {
setLoading(false);
}
};

const editPickupEvent: SubmitHandler<FormValues> = async formData => {
setLoading(true);

const {
title,
start: isoStart,
end: isoEnd,
linkedEventUuid,
description,
orderLimit: rawOrderLimit,
} = formData;

const start = new Date(isoStart).toISOString();
const end = new Date(isoEnd).toISOString();
const orderLimit = parseInt(`${rawOrderLimit}`, 10);

try {
await AdminEventManager.editPickupEvent({
pickupEvent: { title, start, end, description, orderLimit, linkedEventUuid },
uuid: defaultData.uuid ?? '',
token: token,

onSuccessCallback: event => {
setLoading(false);
showToast('Pickup Event Edit Successfully!', '', [
{
text: 'View Live Pickup Event Page',
onClick: () => router.push(`${config.admin.store.pickup}/${event.uuid}`),
},
]);
},
onFailCallback: error => {
setLoading(false);
reportError('Unable to edit pickup event', error);
},
});
} catch (error) {
reportError('Could not save changes', error);
} finally {
setLoading(false);
}
};

const deletePickupEvent = async () => {
setLoading(true);

try {
await AdminEventManager.deletePickupEvent({
event: defaultData.uuid ?? '',
token: token,

onSuccessCallback: () => {
setLoading(false);
showToast('Pickup Event Deleted Successfully!', '');
router.push(config.admin.store.pickup);
},
onFailCallback: error => {
setLoading(false);
reportError('Unable to delete pickup event', error);
},
});
} catch (error) {
reportError('Could not delete pickup event', error);
setLoading(false);
}
};

const defaultFormText = loading ? 'Loading events from API...' : 'Select an Event';

return (
<form onSubmit={handleSubmit(mode === 'edit' ? editPickupEvent : createPickupEvent)}>
<div className={style.header}>
<h1>{mode === 'edit' ? 'Modify' : 'Create'} Pickup Event</h1>

{defaultData.uuid ? (
<Link
className={style.viewPage}
href={`${config.admin.store.pickup}/${defaultData.uuid}`}
>
View pickup event page
<BsArrowRight aria-hidden />
</Link>
) : null}
</div>

<div className={style.form}>
<label htmlFor="title">Title</label>
<DetailsFormItem error={errors.title?.message}>
<input
type="text"
id="title"
placeholder="The Raccoon Pickup Event"
{...register('title', {
required: 'Required',
})}
/>
</DetailsFormItem>

<label htmlFor="start">Starts At</label>
<DetailsFormItem error={errors.start?.message}>
<input
type="datetime-local"
id="start"
{...register('start', {
required: 'Required',
})}
/>
</DetailsFormItem>

<label htmlFor="end">Ends At</label>
<DetailsFormItem error={errors.end?.message}>
<input
type="datetime-local"
id="end"
{...register('end', {
required: 'Required',
})}
/>
</DetailsFormItem>

<label htmlFor="description">Description</label>
<DetailsFormItem error={errors.description?.message}>
<textarea
id="description"
{...register('description', {
required: 'Required',
})}
/>
</DetailsFormItem>

<label htmlFor="points">Order Limit</label>
<DetailsFormItem error={errors.orderLimit?.message}>
<input
type="number"
id="orderLimit"
{...register('orderLimit', {
required: 'Required',
})}
/>
</DetailsFormItem>

<label htmlFor="LinkedEvent">Linked Event</label>
<DetailsFormItem error={errors.linkedEventUuid?.message}>
<select
id=""
placeholder={defaultFormText}
defaultValue={defaultFormText}
{...register('linkedEventUuid', {})}
>
<option disabled>{defaultFormText}</option>

{upcomingEvents?.map(event => (
<option key={event.uuid} value={event.uuid}>
{event.title} ({DateTime.fromISO(event.start).toFormat('f')})
</option>
))}
</select>
</DetailsFormItem>
</div>
<div className={style.submitButtons}>
{mode === 'edit' ? (
<>
<Button submit disabled={loading}>
Save changes
</Button>
<Button onClick={resetForm} disabled={loading} destructive>
Discard changes
</Button>
<Button onClick={deletePickupEvent} disabled={loading} destructive>
Delete pickup event
</Button>
</>
) : (
<>
<Button submit disabled={loading}>
Create pickup event
</Button>
<Button onClick={resetForm} disabled={loading} destructive>
Clear form
</Button>
</>
)}
</div>
</form>
);
};

export default AdminPickupEventForm;
29 changes: 29 additions & 0 deletions src/components/admin/event/AdminPickupEvent/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@use 'src/styles/vars.scss' as vars;

.header {
align-items: center;
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin-bottom: 1rem;

h1 {
font-size: 2rem;
}
}

.form {
column-gap: 8px;
display: grid;
grid-template-columns: 1fr 3fr;
row-gap: 1rem;
}

.submitButtons {
display: flex;
gap: 1rem;
}

:export {
#{defaultThemeColorHex}: vars.$light-primary-2;
}
15 changes: 15 additions & 0 deletions src/components/admin/event/AdminPickupEvent/style.module.scss.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export type Styles = {
addImage: string;
defaultThemeColorHex: string;
form: string;
header: string;
photos: string;
submitButtons: string;
viewPage: string;
};

export type ClassNames = keyof Styles;

declare const styles: Styles;

export default styles;
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ const CollectionDetailsForm = ({ mode, defaultData, token }: IProps) => {
showToast('Collection created successfully!', '', [
{
text: 'Continue editing',
onClick: () => router.push(`${config.store.collectionRoute}/${uuid}/edit`),
onClick: () => router.push(`${config.store.collectionRoute}/${uuid}/edit`), // link to continue editing the item page
},
]);
router.replace(`${config.store.collectionRoute}/${uuid}`);
router.replace(`${config.store.collectionRoute}/${uuid}`); // change link of page to be view, not new item
} catch (error) {
reportError('Could not create collection', error);
setLoading(false);
Expand Down
Loading

0 comments on commit efe5000

Please sign in to comment.