Skip to content

Commit

Permalink
Merge branch 'develop' into component-reworks
Browse files Browse the repository at this point in the history
  • Loading branch information
nl32 committed Sep 30, 2024
2 parents cc338db + da3ca59 commit db5daed
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 66 deletions.
26 changes: 19 additions & 7 deletions src/app/manage/[clubId]/create/CreateEventForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub
watch,
setValue,
getValues,
control,
} = useForm<z.infer<typeof createEventSchema>>({
resolver: zodResolver(createEventSchema),
defaultValues: {
Expand All @@ -29,6 +30,7 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub
});
const router = useRouter();
const [watchDescription, watchStartTime] = watch(['description', 'startTime']);
const [loading, setLoading] = useState(false);
const [eventPreview, setEventPreview] = useState<RouterOutputs['event']['findByFilters']['events'][number]>({
name: "",
clubId,
Expand All @@ -52,8 +54,8 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub
location: location || "",
liked: false,
id: "",
startTime: startTime?.toString() === "" || startTime == undefined ? new Date(Date.now()) : new Date(startTime),
endTime: endTime?.toString() === "" || endTime?.toString() == "Invalid Date" || !endTime ? new Date(Date.now()) : new Date(endTime),
startTime: startTime?.toString() === "" || startTime === undefined ? new Date(Date.now()) : new Date(startTime),
endTime: endTime?.toString() === "" || endTime?.toString() === "Invalid Date" || !endTime ? new Date(Date.now()) : new Date(endTime),
club,
});
}
Expand All @@ -65,11 +67,17 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub
}, [router, watch, officerClubs]);

const createMutation = api.event.create.useMutation({
onSuccess: () => { location.reload(); }
onSuccess: (data) => { if (data) {
router.push(`/event/${data}`);
} },
onError: () => {
setLoading(false);
}
})

const onSubmit = handleSubmit((data: z.infer<typeof createEventSchema>) => {
if (!createMutation.isPending) {
if (!createMutation.isPending && !loading) {
setLoading(true);
createMutation.mutate(data);
}
});
Expand All @@ -89,7 +97,7 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub
<div className="event-pic w-full">
<h1 className="font-bold mb-4">Event Picture</h1>
<p className="upload-label text-xs font-bold mb-11">Drag or choose file to upload</p>
<div className="upload-box bg-[#E9EAEF] w-full h-48 rounded-md flex items-center flex-col justify-center gap-6">
<div className="upload-box bg-[#E9EAEF] w-full h-48 rounded-md flex items-center flex-col justify-center gap-6 opacity-50">
<UploadIcon />
<p className="font-bold text-xs">JPEG, PNG, or SVG</p>
</div>
Expand Down Expand Up @@ -118,8 +126,12 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub
placeholder="Event description" />
</div>
</div>
<TimeSelect register={register} setValue={setValue} getValues={getValues} watchStartTime={watchStartTime} />
<input className="bg-[#3361FF] text-white py-6 hover:cursor-pointer font-black text-xs rounded-md" type="submit" value="Create Event" />
<TimeSelect setValue={setValue} getValues={getValues} watchStartTime={watchStartTime} control={control} />
<input
type="submit"
value="Create Event"
className={`bg-[#3361FF] ${loading ? "opacity-40" : ""} text-white py-6 hover:cursor-pointer font-black text-xs rounded-md`}
/>
</div>
<div className="form-preview w-64 flex flex-col gap-14">
<h1 className="text-lg font-bold">Preview</h1>
Expand Down
99 changes: 41 additions & 58 deletions src/app/manage/[clubId]/create/TimeSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,84 +1,67 @@
'use client'
import { useEffect, useState } from "react";
import type {
UseFormRegister,
UseFormSetValue,
UseFormGetValues,
Control
} from "react-hook-form";
import {
Controller
} from "react-hook-form";
import type { createEventSchema } from "@src/utils/formSchemas";
import type { z } from "zod";

interface Props {
register: UseFormRegister<z.infer<typeof createEventSchema>>,
setValue: UseFormSetValue<z.infer<typeof createEventSchema>>,
getValues: UseFormGetValues<z.infer<typeof createEventSchema>>,
watchStartTime: Date,
control: Control<z.infer<typeof createEventSchema>>,
}

const TimeSelect = ({ register, setValue, getValues, watchStartTime }: Props) => {
const [multiDay, setMultiDay] = useState(false);
const [numHours, setNumHours] = useState(2);

useEffect(() => {
// If not multi-day, set end time to start time + numHours
if (!multiDay && watchStartTime !== undefined) {
const date = new Date(watchStartTime);
date.setHours(date.getHours() + numHours);
setValue("endTime", date);
}

// If start time is after end time, set end time to start time
if (new Date(watchStartTime) > new Date(getValues('endTime'))) {
setValue('endTime', watchStartTime);
}
}, [setValue, getValues, watchStartTime, multiDay, numHours])

const TimeSelect = ({ setValue, getValues, watchStartTime, control }: Props) => {
return (<>
<div className="multi-day flex justify-between w-full">
<div className="left">
<h1 className="font-bold mb-2">Multi-Day Event</h1>
<p className="font-bold text-xs">Does the event last longer than one day?</p>
</div>
<div className="right">
<div className="h-fit flex items-center gap-6">
<div
className={`toggle-multi-day relative hover:cursor-pointer ${multiDay ? "bg-[#3361FF] after:bg-white after:translate-x-[20px]" : "bg-white after:bg-[#E1E5ED]"} w-[50px] h-[30px] rounded-2xl transition-colors duration-150 after:top-[2px] after:absolute after:left-[2px] after:transition-tranform after:duration-150 after:rounded-2xl after:content-[''] after:h-[26px] after:w-[26px]`}
onClick={() => {
// If switching to multiDay, clear endTime
if (!multiDay) {
setValue('endTime', new Date(NaN));
}
setMultiDay(!multiDay);
}} ></div>
<p className="font-bold inline-block w-[30px] text-right text-xs">{multiDay ? "Yes" : "No"}</p>
</div>
</div>
</div>
<div className="event-duration flex gap-32">
<div className="flex-1 justify-end flex flex-col">
<h1 className="font-bold mb-2 block">Duration</h1>
<label htmlFor="startTime" className="text-xs font-bold mb-2">Start Time</label>
<input {...register("startTime")} type="datetime-local" className="outline-none w-full block p-2 text-xs rounded-md text-[#7D8FB3]" />
<Controller
control={control}
name="startTime"
render={({ field: { value, ref, onChange } }) => (
<input
ref={ref}
type="datetime-local"
value={value ? new Date(value.getTime() - value.getTimezoneOffset() * 60 * 1000).toISOString().slice(0, 16) : ""}
onChange={(e) => {
if (!getValues("endTime") || new Date(e.currentTarget.value) > getValues("endTime")) {
// Add 1 hr to new start time
setValue("endTime", new Date(new Date(e.currentTarget.value).getTime() + 60 * 60 * 1000));
}
onChange(new Date(e.currentTarget.value));
}}
className="outline-none w-full block p-2 text-xs rounded-md text-[#7D8FB3]" />
)}
rules={{
required: true,
}} />
</div>
{ multiDay ?
<div className="flex-1 justify-end flex flex-col">
<label htmlFor="endTime" className="text-xs font-bold mb-2">End Time</label>
<input {...register("endTime")} type="datetime-local"
onInput={(e) => { if (new Date(e.currentTarget.value) < new Date(watchStartTime)) setValue('endTime', watchStartTime); }}
min={watchStartTime?.toString()}
className="outline-none w-full block p-2 text-xs rounded-md text-[#7D8FB3]"
/>
</div>
:
<div className="flex-1 justify-end flex flex-col">
<label htmlFor="endTime" className="text-xs font-bold mb-2">Number of Hours</label>
<select className="outline-none p-[9px] text-xs rounded-md" id="endTime" value={numHours} onInput={(e) => {setNumHours(Number(e.currentTarget.value))}}>
{Array(24).fill(0).map((_, i) => (
<option className="" value={i+1} key={i}>{i+1} Hour{i+1 > 1 && "s"}</option>
))}
</select>
<Controller
control={control}
name="endTime"
render={({ field: { value, ref, onChange } }) => (
<input
ref={ref}
type="datetime-local"
min={watchStartTime ? new Date(new Date(watchStartTime).getTime() - new Date(watchStartTime).getTimezoneOffset() * 60 * 1000).toISOString().slice(0, 16) : ""}
value={value ? new Date(value.getTime() - value.getTimezoneOffset() * 60 * 1000).toISOString().slice(0, 16) : ""}
onChange={(e) => onChange(new Date(e.currentTarget.value))}
className="outline-none w-full block p-2 text-xs rounded-md text-[#7D8FB3]" />
)}
rules={{
required: true,
}} />
</div>
}
</div>
</>);
}
Expand Down
4 changes: 3 additions & 1 deletion src/server/api/routers/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,9 @@ export const eventRouter = createTRPCRouter({
throw new TRPCError({ code: 'UNAUTHORIZED' });
}

await ctx.db.insert(events).values({ ...input });
const res = await ctx.db.insert(events).values({ ...input }).returning({ id: events.id });
if (res.length == 0) throw "Failed to add event";
return res[0]?.id;
}),
byName: publicProcedure.input(byNameSchema).query(async ({ input, ctx }) => {
const { name, sortByDate } = input;
Expand Down

0 comments on commit db5daed

Please sign in to comment.