bringing in dropdown library

This commit is contained in:
Mikayla Dobson
2023-02-15 12:09:04 -06:00
parent a30960a1b4
commit 1daf3418ce
7 changed files with 119 additions and 6 deletions

View File

@@ -15,6 +15,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.4.3", "react-router-dom": "^6.4.3",
"react-select": "^5.7.0",
"sass": "^1.56.1", "sass": "^1.56.1",
"uuid": "^9.0.0" "uuid": "^9.0.0"
}, },

View File

@@ -23,6 +23,7 @@ import { TokenType } from './util/types';
import './sass/App.scss'; import './sass/App.scss';
import handleToken from './util/handleToken'; import handleToken from './util/handleToken';
import AddFriends from './components/pages/AddFriends'; import AddFriends from './components/pages/AddFriends';
import Sandbox from './components/Sandbox';
function App() { function App() {
const { setUser, token, setToken } = useAuthContext(); const { setUser, token, setToken } = useAuthContext();
@@ -64,6 +65,7 @@ function App() {
<Route path="/add-recipe" element={<AddRecipe />} /> <Route path="/add-recipe" element={<AddRecipe />} />
<Route path="/grocery-list" element={<GroceryListCollection />} /> <Route path="/grocery-list" element={<GroceryListCollection />} />
<Route path="/grocery-list/:id" element={<GroceryList />} /> <Route path="/grocery-list/:id" element={<GroceryList />} />
<Route path="/sandbox" element={<Sandbox />} />
</Routes> </Routes>
</div> </div>
</BrowserRouter> </BrowserRouter>

View File

@@ -0,0 +1,97 @@
import Select, { MultiValue } from "react-select";
import Creatable, { useCreatable } from "react-select/creatable";
import { useEffect, useState } from "react"
import { useAuthContext } from "../context/AuthContext";
import { ICollection, IIngredient } from "../schemas";
import { Button, Page } from "./ui";
import API from "../util/API";
interface OptionType {
value: number
label: string
}
export default function Sandbox() {
const [ingredients, setIngredients] = useState<Array<IIngredient>>([]);
const [collections, setCollections] = useState<Array<OptionType>>([]);
const [newEntries, setNewEntries] = useState<Array<OptionType>>([]);
const [selections, setSelections] = useState<Array<OptionType>>([]);
const { user, token } = useAuthContext();
function handleNewIngredient(name: string) {
if (!user || !user.id) return;
let maxID = 0;
ingredients.forEach((entry: IIngredient) => {
if (entry.id! > maxID) {
maxID = entry.id!;
}
});
const newEntry: OptionType = {
label: name,
value: maxID + 1
}
const newIngredient: IIngredient = {
id: maxID + 1,
name: name,
createdbyid: user.id
}
setIngredients(prev => [...prev, newIngredient]);
setNewEntries(prev => [...prev, newEntry]);
}
function handleChange(event: MultiValue<OptionType>) {
setSelections(prev => [...prev, ...event])
}
async function bulkInsertIngredients() {
if (!user || !token) return;
console.log(newEntries.length - ingredients.length);
}
useEffect(() => {
token && (async() => {
const ingredients = new API.Ingredient(token);
const collections = new API.Collection(token);
const allIngredients = await ingredients.getAll();
if (allIngredients) {
setNewEntries(prev => [...prev, ...allIngredients]);
setIngredients(allIngredients.map((each: IIngredient) => {
return { label: each.name, value: each.id }
}));
}
const myCollections = await collections.getAllAuthored();
if (myCollections) setCollections(myCollections.map((each: ICollection) => {
return { label: each.name, value: each.id }
}))
})();
}, [token])
useEffect(() => {
console.log(newEntries);
}, [newEntries])
return (
<Page>
<h1>Sandbox</h1>
<p>Ingredients:</p>
{ ingredients
? <Creatable isMulti value={selections} onChange={(value: MultiValue<OptionType>) => handleChange(value)} onCreateOption={handleNewIngredient} options={newEntries} />
: <p>Loading...</p>
}
<p>My collections:</p>
{ collections ? <Select options={collections} /> : <p>Loading...</p> }
<Button onClick={bulkInsertIngredients}>Go</Button>
</Page>
)
}

View File

@@ -85,7 +85,7 @@ const Form: FC<FormProps> = ({ parent, _config }) => {
break; break;
} }
return null; return [];
} }
// mount the form once config has been loaded // mount the form once config has been loaded
@@ -108,7 +108,7 @@ const Form: FC<FormProps> = ({ parent, _config }) => {
return null; return null;
})(); })();
return <Selector<StrongType> optionList={storedResult || []} /> return <Selector<StrongType> config={config} idx={i} optionList={storedResult || []} />
} else { } else {
return ( return (
<div className="form-row" id={`${config.parent}-row-${i}`} key={v4()}> <div className="form-row" id={`${config.parent}-row-${i}`} key={v4()}>

View File

@@ -1,16 +1,24 @@
import reactSelect from "react-select"
import makeAnimated from "react-select/animated";
import { FormConfig } from "./Form"
import { v4 } from "uuid"
interface Entity { interface Entity {
id: string | number id: string | number
name?: string name?: string
} }
function Selector<T extends Entity>({ optionList }: { optionList: Array<T> }) { function Selector<T extends Entity>({ config, idx, optionList }: { config: FormConfig<T>, idx: number, optionList: Array<T> }) {
// const Selector: FC<{ optionList: Array<T extends HasID> }> = ({ optionList }) => { // const Selector: FC<{ optionList: Array<T extends HasID> }> = ({ optionList }) => {
return ( return (
<div className="form-row form-row-selector" id={`${config.parent}-row-${idx}`} key={v4()}>
<label htmlFor={`${config.parent}-${config.keys[idx]}`}>{config.labels![idx]}</label>
<select className="ui-select-component"> <select className="ui-select-component">
{ optionList.map(item => { optionList.map(item =>
<option id={`select-item-${item.name}-${item.id}`}>{item.name}</option> <option id={`select-item-${item.name}-${item.id}`}>{item.name}</option>
)} )}
</select> </select>
</div>
) )
} }

View File

@@ -17,6 +17,11 @@
border-radius: 4px; border-radius: 4px;
width: 65%; width: 65%;
} }
select {
width: 65%;
margin: 0;
}
} }
.form-row-editor { .form-row-editor {

View File

@@ -186,7 +186,7 @@ module API {
export class Ingredient extends RestController<IIngredient> { export class Ingredient extends RestController<IIngredient> {
constructor(token: string) { constructor(token: string) {
super(Settings.getAPISTRING() + "/app/ingredients", token); super(Settings.getAPISTRING() + "/app/ingredient", token);
} }
} }