Skip to content

Commit

Permalink
Convert map url to dropdown
Browse files Browse the repository at this point in the history
Can also manually enter url
  • Loading branch information
Timothy-Gonzalez committed Feb 23, 2025
1 parent 1685aa2 commit cedd8e8
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 9 deletions.
32 changes: 26 additions & 6 deletions app/events/EventEditPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Checkbox, { FormikCheckbox } from "@/components/Checkbox"
import styles from "./EventEditPopup.module.scss"
import { CreateEventRequest, EventId } from "@/generated"
import LocationInput from "./LocationInput"
import { getMetadataSuffix, useMetadata } from "@/util/metadata"

const publicEventTypes = [
"MEAL",
Expand All @@ -19,11 +20,15 @@ const publicEventTypes = [
]
const staffEventTypes = ["MEETING", "STAFFSHIFT", "OTHER"]

type EventEditForm = Omit<CreateEventRequest, "eventType"> & {
type EventEditForm = Omit<CreateEventRequest, "eventType" | "mapImageUrl"> & {
eventType: {
label: CreateEventRequest["eventType"]
value: CreateEventRequest["eventType"]
} | null
mapImageUrl: {
label: string
value: string
} | null
}

interface EventEditProps {
Expand Down Expand Up @@ -56,15 +61,13 @@ export default function EventEditPopup({
endTime: time,
name: "",
description: "",
// eventType: "",
locations: [],
sponsor: "",
points: 0,
isPrivate: false,
displayOnStaffCheckIn: false,
isAsync: false,
isStaff: staffView,
mapImageUrl: "",
isPro: false,
...initialEvent,
eventType: initialEvent.eventType
Expand All @@ -73,6 +76,12 @@ export default function EventEditPopup({
value: initialEvent.eventType,
}
: null,
mapImageUrl: initialEvent.mapImageUrl
? {
label: getMetadataSuffix(initialEvent.mapImageUrl),
value: initialEvent.mapImageUrl,
}
: null,
}

const [expires, setExpires] = useState(!!initialValues.exp)
Expand All @@ -84,11 +93,20 @@ export default function EventEditPopup({
const newEvent: CreateEventRequest = {
...values,
eventType: values.eventType.value,
mapImageUrl: values.mapImageUrl
? values.mapImageUrl.value
: undefined,
exp: expires ? values.exp : 0,
}
onUpdateEvent(editingEventId, newEvent)
}

const mapUrls = useMetadata("maps")
const mapUrlOptions = mapUrls.map(({ path, url }) => ({
label: path,
value: url,
}))

return (
<div className={styles["event-edit-popup"]}>
<div className={styles["popup-background"]} onClick={onDismiss} />
Expand Down Expand Up @@ -181,17 +199,19 @@ export default function EventEditPopup({
)}
placeholder="Type"
/>

<Field
className={styles["form-field"]}
name="points"
placeholder="Points"
type="number"
/>
<Field
className={styles["form-field"]}
<SelectField
className={styles.select}
name="mapImageUrl"
menuPlacement="top"
options={mapUrlOptions}
placeholder="Map Image URL"
creatable
/>
<Field
className={styles["form-margins"]}
Expand Down
14 changes: 11 additions & 3 deletions components/SelectField/SelectField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import Select, { Props as SelectProps, ThemeConfig } from "react-select"
import { useField } from "formik"

import { getColors } from "@/app/constants"
import CreatableSelect from "react-select/creatable"

type StyledSelectProps<T> = SelectProps<{ label: string; value: T }>
type StyledSelectProps<T> = SelectProps<{ label: string; value: T }> & {
creatable?: boolean
}

export function StyledSelect<T>(props: SelectProps<T>) {
export function StyledSelect<T>({
creatable = false,
...props
}: StyledSelectProps<T>) {
const { primaryColor, primaryColorLight } = getColors()
const theme: ThemeConfig = (defaultTheme) => ({
...defaultTheme,
Expand All @@ -18,7 +24,9 @@ export function StyledSelect<T>(props: SelectProps<T>) {
},
})

return <Select theme={theme} {...props} />
const Component = creatable ? CreatableSelect : Select

return <Component theme={theme} {...props} />
}

type SelectFieldProps<T> = StyledSelectProps<T> & { name: string }
Expand Down
59 changes: 59 additions & 0 deletions util/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useEffect, useState } from "react"

const CONTENT_API_ENDPOINT =
"https://api.github.com/repos/HackIllinois/adonix-metadata/contents"
const RAW_CONTENT_PREFIX =
"https://raw.githubusercontent.com/HackIllinois/adonix-metadata/refs/heads/main/"

export interface MetadataItem {
path: string
url: string
}

// Gets the possible options for metadata under a path
async function getMetadata(path: string): Promise<MetadataItem[]> {
const key = `METADATA_${path}`
const stored = sessionStorage.getItem(key)
if (stored && JSON.parse(stored).expiry > Date.now()) {
return JSON.parse(stored).data
}

const result = await fetch(`${CONTENT_API_ENDPOINT}/${path}`)
const raw = (await result.json()) as { name: string; path: string }[]
const metadata = raw.map(({ path }) => ({
path,
url: `${RAW_CONTENT_PREFIX}${path}`,
}))

sessionStorage.setItem(
key,
JSON.stringify({
expiry: Date.now() + 60 * 1000,
data: metadata,
}),
)

return metadata
}

// Hook for getting the possible options for metadata under a path
export function useMetadata(path = "") {
const [metadata, setMetadata] = useState<MetadataItem[]>([])

useEffect(() => {
const fetchMetadata = async () => {
setMetadata(await getMetadata(path))
}
fetchMetadata()
}, [path])

return metadata
}

// Gets the suffix of a metadata url by removing adonix prefix
export function getMetadataSuffix(url: string) {
if (url.startsWith(RAW_CONTENT_PREFIX)) {
return url.substring(RAW_CONTENT_PREFIX.length)
}
return url
}

0 comments on commit cedd8e8

Please sign in to comment.