Skip to content

Commit

Permalink
feat: add props to custom input, cleanup misc.
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinWu098 committed Jul 22, 2024
1 parent fcc0463 commit 2920c18
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 79 deletions.
123 changes: 64 additions & 59 deletions sanity-dauci/components/SelectWithCustomInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,76 @@ import React, { useState, useEffect, FormEvent } from "react";
import { TextInput, Stack, Select, Card } from "@sanity/ui";
import { set, unset, StringInputProps, StringSchemaType } from "sanity";

export const SelectWithCustomInput = React.forwardRef(function SelectWithCustomInput(
props: StringInputProps<StringSchemaType>,
ref: React.ForwardedRef<HTMLSelectElement>,
) {
const { value, onChange } = props;
const [selectedValue, setSelectedValue] = useState(value || "other");
const [customValue, setCustomValue] = useState("");
export const SelectWithCustomInput = React.forwardRef(
function SelectWithCustomInput(
props: StringInputProps<StringSchemaType> & {
options: { title: string; value: string }[];
},
ref: React.ForwardedRef<HTMLSelectElement>,
) {
const { value, onChange, options } = props;
const [selectedValue, setSelectedValue] = useState(value || "other");
const [customValue, setCustomValue] = useState("");

const predefinedValues = [
{ title: "RSVP Form", value: "RSVP Form" },
{ title: "Recording", value: "Recording" },
{ title: "Resources", value: "Resources" },
{ title: "Slides", value: "Slides" },
{ title: "Zoom Link", value: "Zoom Link" },
];
const predefinedValues = options;

useEffect(() => {
if (value && !predefinedValues.map((option) => option.value).includes(value)) {
setSelectedValue("other");
setCustomValue(value);
}
}, [value]);
useEffect(() => {
if (
value &&
!predefinedValues.map((option) => option.value).includes(value)
) {
setSelectedValue("other");
setCustomValue(value);
}
}, [value]);

const handleSelectChange = (event: FormEvent<HTMLSelectElement>) => {
const newValue = event.currentTarget.value;
const handleSelectChange = (event: FormEvent<HTMLSelectElement>) => {
const newValue = event.currentTarget.value;

setSelectedValue(newValue);
if (newValue === "other") {
onChange(customValue ? set(customValue) : unset());
} else {
setCustomValue(""); // Reset custom value when a predefined option is selected
onChange(set(newValue));
}
};
setSelectedValue(newValue);
if (newValue === "other") {
onChange(customValue ? set(customValue) : unset());
} else {
setCustomValue(""); // Reset custom value when a predefined option is selected
onChange(set(newValue));
}
};

const handleInputChange = (event: FormEvent<HTMLInputElement>) => {
const newValue = event.currentTarget.value;
setCustomValue(newValue);
const handleInputChange = (event: FormEvent<HTMLInputElement>) => {
const newValue = event.currentTarget.value;
setCustomValue(newValue);

if (selectedValue === "other") {
onChange(newValue ? set(newValue) : unset());
}
};
if (selectedValue === "other") {
onChange(newValue ? set(newValue) : unset());
}
};

return (
<Stack space={3}>
<Card>
<Select onChange={handleSelectChange} value={selectedValue} ref={ref}>
{predefinedValues.map((option) => (
<option key={option.value} value={option.value}>
{option.title}
</option>
))}
<option value="other">Other</option>
</Select>
</Card>
{selectedValue === "other" && (
return (
<Stack space={3}>
<Card>
<TextInput
value={customValue}
onChange={handleInputChange}
placeholder="Enter other type"
/>
<Select
onChange={handleSelectChange}
value={selectedValue}
ref={ref}
>
{predefinedValues.map((option) => (
<option key={option.value} value={option.value}>
{option.title}
</option>
))}
<option value="other">Other</option>
</Select>
</Card>
)}
</Stack>
);
});
{selectedValue === "other" && (
<Card>
<TextInput
value={customValue}
onChange={handleInputChange}
placeholder="Enter other type"
/>
</Card>
)}
</Stack>
);
},
);
69 changes: 54 additions & 15 deletions sanity-dauci/schemaTypes/event-schema.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,47 @@
import { defineField, defineType } from "sanity";
import { SelectWithCustomInput } from "../components/SelectWithCustomInput";
import React from "react";

type Link = {
label?: string;
link?: string;
};

const EVENT_OPTIONS = [
{
title: "Industry Speaker",
value: "Industry Speaker",
},
{ title: "Workshop", value: "Workshop" },
{ title: "Social", value: "Social" },
{ title: "Project Teams", value: "Project Teams" },
{ title: "Fundraiser", value: "Fundraiser" },
{ title: "AMA", value: "AMA" },
];

const LINK_OPTIONS = [
{
title: "RSVP Form",
value: "RSVP Form",
},
{
title: "Recording",
value: "Recording",
},
{
title: "Resources",
value: "Resources",
},
{
title: "Slides",
value: "Slides",
},
{
title: "Zoom Link",
value: "Zoom Link",
},
];

export default defineType({
name: "event",
title: "Event",
Expand All @@ -19,7 +55,7 @@ export default defineType({
}),
defineField({
name: "time",
title: "Time",
title: "Time (PST)",
type: "datetime",
validation: (Rule) => Rule.required().error("Time is required"),
}),
Expand All @@ -31,25 +67,21 @@ export default defineType({
}),
defineField({
name: "type",
title: "Type",
title: "Event Type",
type: "string",
options: {
list: [
{ title: "Industry Speaker", value: "Industry Speaker" },
{ title: "Workshop", value: "Workshop" },
{ title: "Social", value: "Social" },
{ title: "Project Teams", value: "Project Teams" },
{ title: "Fundraiser", value: "Fundraiser" },
{ title: "AMA", value: "AMA" },
],
components: {
input: (props) => (
<SelectWithCustomInput {...props} options={EVENT_OPTIONS} />
),
},
validation: (Rule) => Rule.required().error("Type is required"),
}),
defineField({
name: "desc",
title: "Description",
type: "text",
validation: (Rule) => Rule.required().error("Description is required"),
validation: (Rule) =>
Rule.required().error("Description is required"),
}),
defineField({
name: "place",
Expand All @@ -72,15 +104,22 @@ export default defineType({
title: "Label",
type: "string",
components: {
input: SelectWithCustomInput,
input: (props) => (
<SelectWithCustomInput
{...props}
options={LINK_OPTIONS}
/>
),
},
validation: (Rule) => Rule.required().error("Label is required"),
validation: (Rule) =>
Rule.required().error("Label is required"),
}),
defineField({
name: "link",
title: "URL",
type: "url",
validation: (Rule) => Rule.required().error("URL is required"),
validation: (Rule) =>
Rule.required().error("URL is required"),
}),
],
validation: (Rule) =>
Expand Down
12 changes: 10 additions & 2 deletions src/app/pages/Events/Events.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ import EventCard from "./components/EventCard/EventCard.js";
import { useEvents } from "./useEvents.js";

const Events = () => {
const events = useEvents();
const { events, loading } = useEvents();

if (loading) {
return (
<Helmet>
<title>Events - Design at UCI</title>
</Helmet>
);
}

return (
<>
<Helmet>
<title>Events Design at UCI</title>
<title>Events - Design at UCI</title>
</Helmet>
<Section
className={`center short ${
Expand Down
12 changes: 10 additions & 2 deletions src/app/pages/Events/EventsAll.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@ import { EventCard } from "./components";
import { useEvents } from "./useEvents";

const EventsAll = () => {
const events = useEvents();
const { events, loading } = useEvents();

if (loading) {
return (
<Helmet>
<title>Event Archive - Design at UCI</title>
</Helmet>
);
}

return (
<>
<Helmet>
<title>Event Archive Design at UCI</title>
<title>Event Archive - Design at UCI</title>
</Helmet>
<Section className="center short">
<Text size="XL">All Events</Text>
Expand Down
6 changes: 5 additions & 1 deletion src/app/pages/Events/useEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ const legacyEvents = parseEvents(EVENT_DATA); // events from manual JSON file

export const useEvents = () => {
const [events, setEvents] = useState([]);
const [loading, setLoading] = useState(false);

const fetchEvents = useCallback(async () => {
setLoading(true);
const result = await client.fetch(
`*[_type == "event"] | order(time desc)`,
{},
);

setLoading(false);
return result.map((item) => ({
title: item.title,
time: item.time,
Expand Down Expand Up @@ -43,5 +47,5 @@ export const useEvents = () => {
getEvents();
}, [fetchEvents]);

return events;
return { events, loading };
};

0 comments on commit 2920c18

Please sign in to comment.