mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-08-04 04:35:19 +02:00
Autocomplete for plans activity types
This commit is contained in:
parent
870d8234b8
commit
349520572d
6 changed files with 109 additions and 9 deletions
33
src/lib/components/AutoComplete.svelte
Normal file
33
src/lib/components/AutoComplete.svelte
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let items: String[] = [];
|
||||||
|
export let selectedItem;
|
||||||
|
|
||||||
|
$: inputVal = "";
|
||||||
|
|
||||||
|
function onItemClicked(item: String) {
|
||||||
|
selectedItem = item;
|
||||||
|
inputVal = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
$: filteredItems = items.filter(function (item) {
|
||||||
|
return item.toLowerCase().includes(inputVal.toLowerCase());
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="dropdown">
|
||||||
|
<input
|
||||||
|
class="input input-bordered"
|
||||||
|
placeholder="Existing Activity Types"
|
||||||
|
bind:value={inputVal}
|
||||||
|
/>
|
||||||
|
<ul
|
||||||
|
tabindex="0"
|
||||||
|
class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52 max-h-80 flex-nowrap overflow-auto"
|
||||||
|
>
|
||||||
|
{#each filteredItems as item}
|
||||||
|
<li>
|
||||||
|
<a on:click|preventDefault={() => onItemClicked(item)}>{item}</a>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</div>
|
|
@ -17,13 +17,35 @@
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { addActivityType, generateDescription, getImage } from "$lib";
|
import { addActivityType, generateDescription, getImage } from "$lib";
|
||||||
|
import AutoComplete from "./AutoComplete.svelte";
|
||||||
let modal: HTMLDialogElement;
|
let modal: HTMLDialogElement;
|
||||||
|
|
||||||
onMount(() => {
|
let activityTypes: string[] = [];
|
||||||
|
|
||||||
|
$: selected = "";
|
||||||
|
|
||||||
|
// on selection add to activityTypes
|
||||||
|
$: {
|
||||||
|
if (selected) {
|
||||||
|
newAdventure = addActivityType(selected, newAdventure);
|
||||||
|
|
||||||
|
if (activityInput.length === 0) {
|
||||||
|
activityInput = selected;
|
||||||
|
} else {
|
||||||
|
activityInput = activityInput + ", " + selected;
|
||||||
|
}
|
||||||
|
selected = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
modal = document.getElementById("my_modal_1") as HTMLDialogElement;
|
modal = document.getElementById("my_modal_1") as HTMLDialogElement;
|
||||||
if (modal) {
|
if (modal) {
|
||||||
modal.showModal();
|
modal.showModal();
|
||||||
}
|
}
|
||||||
|
let activityFetch = await fetch("/api/activitytypes?type=" + type);
|
||||||
|
let res = await activityFetch.json();
|
||||||
|
activityTypes = res.types;
|
||||||
});
|
});
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
|
@ -133,6 +155,7 @@
|
||||||
bind:value={activityInput}
|
bind:value={activityInput}
|
||||||
class="input input-bordered w-full max-w-xs"
|
class="input input-bordered w-full max-w-xs"
|
||||||
/>
|
/>
|
||||||
|
<AutoComplete items={activityTypes} bind:selectedItem={selected} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="rating">Rating</label>
|
<label for="rating">Rating</label>
|
||||||
|
|
|
@ -5,18 +5,42 @@
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { addActivityType, generateDescription, getImage } from "$lib";
|
import { addActivityType, generateDescription, getImage } from "$lib";
|
||||||
|
import AutoComplete from "./AutoComplete.svelte";
|
||||||
let modal: HTMLDialogElement;
|
let modal: HTMLDialogElement;
|
||||||
|
|
||||||
console.log(adventureToEdit.id);
|
console.log(adventureToEdit.id);
|
||||||
|
|
||||||
let originalName = adventureToEdit.name;
|
let originalName = adventureToEdit.name;
|
||||||
|
|
||||||
onMount(() => {
|
let activityTypes: string[] = [];
|
||||||
|
|
||||||
|
$: selected = "";
|
||||||
|
|
||||||
|
// on selection add to activityTypes
|
||||||
|
$: {
|
||||||
|
if (selected) {
|
||||||
|
adventureToEdit = addActivityType(selected, adventureToEdit);
|
||||||
|
|
||||||
|
if (activityInput.length === 0) {
|
||||||
|
activityInput = selected;
|
||||||
|
} else {
|
||||||
|
activityInput = activityInput + ", " + selected;
|
||||||
|
}
|
||||||
|
selected = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
modal = document.getElementById("my_modal_1") as HTMLDialogElement;
|
modal = document.getElementById("my_modal_1") as HTMLDialogElement;
|
||||||
if (modal) {
|
if (modal) {
|
||||||
modal.showModal();
|
modal.showModal();
|
||||||
}
|
}
|
||||||
activityInput = (adventureToEdit?.activityTypes || []).join(", ");
|
activityInput = (adventureToEdit?.activityTypes || []).join(", ");
|
||||||
|
let activityFetch = await fetch(
|
||||||
|
"/api/activitytypes?type=" + adventureToEdit.type
|
||||||
|
);
|
||||||
|
let res = await activityFetch.json();
|
||||||
|
activityTypes = res.types;
|
||||||
});
|
});
|
||||||
|
|
||||||
function submit() {
|
function submit() {
|
||||||
|
@ -120,6 +144,7 @@
|
||||||
bind:value={activityInput}
|
bind:value={activityInput}
|
||||||
class="input input-bordered w-full max-w-xs"
|
class="input input-bordered w-full max-w-xs"
|
||||||
/>
|
/>
|
||||||
|
<AutoComplete items={activityTypes} bind:selectedItem={selected} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="rating">Rating</label>
|
<label for="rating">Rating</label>
|
||||||
|
|
|
@ -48,5 +48,8 @@ export const GET: RequestHandler = async ({ url, locals }) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// remove duplicates
|
||||||
|
array = [...new Set(array)];
|
||||||
|
|
||||||
return json({ types: array }, { status: 200 });
|
return json({ types: array }, { status: 200 });
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,10 @@ export const load: PageServerLoad = async (event) => {
|
||||||
}
|
}
|
||||||
const response = await event.fetch("/api/planner");
|
const response = await event.fetch("/api/planner");
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
const activityTypes = await event.fetch("/api/activitytypes?type=planner");
|
||||||
|
const activityTypesResult = await activityTypes.json();
|
||||||
return {
|
return {
|
||||||
result,
|
result,
|
||||||
|
activityTypesResult,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,15 +19,16 @@
|
||||||
let adventuresPlans: Adventure[] = [];
|
let adventuresPlans: Adventure[] = [];
|
||||||
let tripPlans: Trip[] = [];
|
let tripPlans: Trip[] = [];
|
||||||
|
|
||||||
|
let activityTypes: String[] = [];
|
||||||
|
|
||||||
let isLoadingIdeas: boolean = true;
|
let isLoadingIdeas: boolean = true;
|
||||||
let isLoadingTrips: boolean = true;
|
let isLoadingTrips: boolean = true;
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
console.log(data);
|
|
||||||
getAllTrips();
|
getAllTrips();
|
||||||
console.log(tripPlans);
|
|
||||||
adventuresPlans = data.result;
|
adventuresPlans = data.result;
|
||||||
isLoadingIdeas = false;
|
isLoadingIdeas = false;
|
||||||
|
activityTypes = data.activityTypesResult.types;
|
||||||
});
|
});
|
||||||
|
|
||||||
let isShowingMoreFields: boolean = false;
|
let isShowingMoreFields: boolean = false;
|
||||||
|
@ -38,8 +39,6 @@
|
||||||
|
|
||||||
let adventureToEdit: Adventure | undefined;
|
let adventureToEdit: Adventure | undefined;
|
||||||
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
function showToast(action: string) {
|
function showToast(action: string) {
|
||||||
toastAction = action;
|
toastAction = action;
|
||||||
isShowingToast = true;
|
isShowingToast = true;
|
||||||
|
@ -65,10 +64,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async function savePlan(event: { detail: Adventure }) {
|
async function savePlan(event: { detail: Adventure }) {
|
||||||
|
let types: String[] = [];
|
||||||
|
if (event.detail.activityTypes && event.detail.activityTypes.length > 0) {
|
||||||
|
types = event.detail.activityTypes;
|
||||||
|
}
|
||||||
let newArray = await saveAdventure(event.detail, adventuresPlans);
|
let newArray = await saveAdventure(event.detail, adventuresPlans);
|
||||||
if (newArray.length > 0) {
|
if (newArray.length > 0) {
|
||||||
adventuresPlans = newArray;
|
adventuresPlans = newArray;
|
||||||
showToast("Adventure updated successfully!");
|
showToast("Adventure updated successfully!");
|
||||||
|
activityTypes = activityTypes.concat(types);
|
||||||
|
activityTypes = [...new Set(activityTypes)];
|
||||||
} else {
|
} else {
|
||||||
showToast("Failed to update adventure");
|
showToast("Failed to update adventure");
|
||||||
}
|
}
|
||||||
|
@ -93,10 +98,16 @@
|
||||||
|
|
||||||
const createNewAdventure = async (event: { detail: Adventure }) => {
|
const createNewAdventure = async (event: { detail: Adventure }) => {
|
||||||
isShowingMoreFields = false;
|
isShowingMoreFields = false;
|
||||||
|
let types: String[] = [];
|
||||||
|
if (event.detail.activityTypes && event.detail.activityTypes.length > 0) {
|
||||||
|
types = event.detail.activityTypes;
|
||||||
|
}
|
||||||
let newArray = await addAdventure(event.detail, adventuresPlans);
|
let newArray = await addAdventure(event.detail, adventuresPlans);
|
||||||
if (newArray.length > 0) {
|
if (newArray.length > 0) {
|
||||||
adventuresPlans = newArray;
|
adventuresPlans = newArray;
|
||||||
showToast("Adventure added successfully!");
|
showToast("Adventure added successfully!");
|
||||||
|
activityTypes = activityTypes.concat(types);
|
||||||
|
activityTypes = [...new Set(activityTypes)];
|
||||||
} else {
|
} else {
|
||||||
showToast("Failed to add adventure");
|
showToast("Failed to add adventure");
|
||||||
}
|
}
|
||||||
|
@ -221,10 +232,12 @@
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center items-center w-full mt-4 mb-4">
|
<div class="flex justify-center items-center w-full mt-4 mb-4">
|
||||||
Filter by: Activity Type
|
Activity Type
|
||||||
<select class="select select-bordered w-full max-w-xs">
|
<select class="select select-bordered w-full max-w-xs">
|
||||||
<option>Han Solo</option>
|
<option value="">All</option>
|
||||||
<option>Greedo</option>
|
{#each activityTypes as type}
|
||||||
|
<option value={type}>{type}</option>
|
||||||
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue