Skip to content

Commit

Permalink
Merge pull request #221 from OxfordRSE/fix-dropdown-courses
Browse files Browse the repository at this point in the history
New process of adding and ordering material sections in the edit eventgroup
  • Loading branch information
alasdairwilson authored Jun 3, 2024
2 parents 46d6222 + b64fde6 commit 02d79fa
Show file tree
Hide file tree
Showing 7 changed files with 353 additions and 48 deletions.
46 changes: 46 additions & 0 deletions components/forms/EventItemAdder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { useState } from "react"
import Stack from "components/ui/Stack"
import type { FieldValues } from "react-hook-form"
import { Button } from "@mui/material"
import SelectSectionField from "components/forms/SelectSectionField"
import type { Option } from "components/forms/SelectSectionField"

interface EventItemAdderProps<T extends FieldValues> {
sectionsOptions: Option[]
selectedOptions: Option[]
setSelectedOptions: React.Dispatch<React.SetStateAction<Option[]>>
handleAddClick: () => void
inputValue?: string
setInputValue: React.Dispatch<React.SetStateAction<string>>
className?: string
}

function EventItemAdder({
sectionsOptions,
selectedOptions,
setSelectedOptions,
handleAddClick,
inputValue,
setInputValue,
className,
}: EventItemAdderProps<FieldValues>) {
return (
<Stack direction="row">
<SelectSectionField
label="Section"
name=""
options={sectionsOptions}
selectedOptions={selectedOptions}
setSelectedOptions={setSelectedOptions}
inputValue={inputValue}
setInputValue={setInputValue}
className={className}
/>
<Button onClick={handleAddClick} variant="contained" size="small" className="rounded">
Add Sections
</Button>
</Stack>
)
}

export default EventItemAdder
89 changes: 89 additions & 0 deletions components/forms/SelectSectionField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from "react"
import { useForm, Control, Controller, FieldPath, FieldValues } from "react-hook-form"
import { Autocomplete, TextField, Checkbox } from "@mui/material"
import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"
import CheckBoxIcon from "@mui/icons-material/CheckBox"
import { Chip } from "@mui/material"

const icon = <CheckBoxOutlineBlankIcon fontSize="small" />
const checkedIcon = <CheckBoxIcon fontSize="small" />

export type Option = {
value: any
label: string
}

type Props<T extends FieldValues> = {
label?: string
name: FieldPath<T>
options: Option[]
rules?: Object
className?: React.ComponentProps<"div">["className"]
selectedOptions: Option[]
setSelectedOptions: React.Dispatch<React.SetStateAction<Option[]>>
inputValue?: string
setInputValue: React.Dispatch<React.SetStateAction<string>>
}

function SelectSectionField<T extends FieldValues>({
label,
name,
options,
className,
selectedOptions,
setSelectedOptions,
inputValue,
setInputValue,
}: Props<T>): React.ReactElement {
const filterOptions = (options: Option[], { inputValue }: { inputValue: string }) => {
return options.filter((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()))
}
return (
<div className={className} id="select">
<Autocomplete
multiple
inputValue={inputValue}
disableCloseOnSelect={true}
onChange={(event, newValue) => setSelectedOptions(newValue)}
value={selectedOptions}
id={name}
options={options}
getOptionLabel={(option) => option.label}
filterOptions={filterOptions}
isOptionEqualToValue={(option, value) => option.value === value.value}
sx={{ width: 1000 }}
renderOption={(props, option, { selected }) => (
<li {...props}>
<Checkbox icon={icon} checkedIcon={checkedIcon} style={{ marginRight: 8 }} checked={selected} />
{option.label}
</li>
)}
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip
label={option.label}
{...getTagProps({ index })}
className="dark:bg-teal-500 dark:text-white"
key={`chip-${option.value}`}
/>
))
}
renderInput={(params) => (
<TextField
{...params}
placeholder="Choose Sections"
label={name}
error={false}
onChange={(e) => setInputValue(e.target.value)}
variant="outlined"
className="block w-full rounded-lg border disabled:cursor-not-allowed disabled:opacity-50 bg-gray-50
border-gray-300 text-gray-900 focus:border-cyan-500 focus:ring-cyan-500 dark:border-gray-600
dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-cyan-500 dark:focus:ring-cyan-500"
/>
)}
/>
</div>
)
}

export default SelectSectionField
2 changes: 0 additions & 2 deletions lib/material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,6 @@ export async function getCourse(repo: string, theme: string, course: string, no_
const summary = (courseObject.attributes.summary as string) || ""
// @ts-expect-error
const dependsOn = (courseObject.attributes.dependsOn as string[]) || []
// @ts-expect-error
const filenames = (courseObject.attributes.files as string[]) || []
const markdown = no_markdown ? "" : (courseObject.body as string)
// @ts-expect-error
const files = courseObject.attributes.files as [string]
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
},
"dependencies": {
"@dnd-kit/core": "^3.0.0",
"@dnd-kit/sortable": "^3.0.0",
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.7.1",
"@mui/icons-material": "5.15.18",
"@mui/material": "^5.2.5",
"@mui/x-date-pickers": "^6.19.0",
"@next-auth/prisma-adapter": "^1.0.5",
Expand Down
8 changes: 2 additions & 6 deletions pages/event/[eventId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ import { makeSerializable } from "lib/utils"
import Content from "components/content/Content"
import NavDiagram from "components/NavDiagram"
import Title from "components/ui/Title"
import type { Event } from "lib/types"
import useSWR, { Fetcher } from "swr"
import type { Event, EventFull } from "lib/types"
import { basePath } from "lib/basePath"
import EventActions from "components/EventActions"
import { Avatar, Button, Card, Tabs } from "flowbite-react"
import EventUsers from "components/EventUsers"
import EventProblems from "components/EventProblems"
import { useForm, Controller, useFieldArray } from "react-hook-form"
import { useSession } from "next-auth/react"
Expand All @@ -25,7 +22,6 @@ import { Event as EventWithUsers } from "pages/api/event/[eventId]"
import Stack from "components/ui/Stack"
import { putEvent } from "lib/actions/putEvent"
import { useEffect, useState } from "react"
import { Prisma } from "@prisma/client"
import SelectField from "components/forms/SelectField"
import Checkbox from "components/forms/Checkbox"
import SubTitle from "components/ui/SubTitle"
Expand Down Expand Up @@ -192,7 +188,7 @@ const Event: NextPage<EventProps> = ({ material, event, pageInfo }) => {
))}
<Button onClick={handleAddGroup}>Add Group</Button>
</div>
<Button type="submit">Save</Button>
<Button type="submit">Save Changes</Button>
</Stack>
</form>
)
Expand Down
Loading

0 comments on commit 02d79fa

Please sign in to comment.