bringing in dropdown library
This commit is contained in:
@@ -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"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
97
client/src/components/Sandbox.tsx
Normal file
97
client/src/components/Sandbox.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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()}>
|
||||||
|
|||||||
@@ -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 (
|
||||||
<select className="ui-select-component">
|
<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">
|
||||||
{ 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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user