1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-24 07:19:36 +02:00

add transportation

This commit is contained in:
Sean Morley 2024-07-28 09:10:59 -04:00
parent 61c3d23efa
commit 6155d531ab
5 changed files with 267 additions and 28 deletions

View file

@ -30,7 +30,7 @@ class TransportationSerializer(serializers.ModelSerializer):
fields = [ fields = [
'id', 'user_id', 'type', 'name', 'description', 'rating', 'id', 'user_id', 'type', 'name', 'description', 'rating',
'link', 'date', 'flight_number', 'from_location', 'to_location', 'link', 'date', 'flight_number', 'from_location', 'to_location',
'is_public', 'collection', 'collection_id', 'created_at', 'updated_at' 'is_public', 'collection', 'created_at', 'updated_at'
] ]
read_only_fields = ['id', 'created_at', 'updated_at'] read_only_fields = ['id', 'created_at', 'updated_at']

View file

@ -11,18 +11,13 @@
let originalName = transportationToEdit.name; let originalName = transportationToEdit.name;
let isPointModalOpen: boolean = false;
import MapMarker from '~icons/mdi/map-marker'; import MapMarker from '~icons/mdi/map-marker';
import Calendar from '~icons/mdi/calendar'; import Calendar from '~icons/mdi/calendar';
import Notebook from '~icons/mdi/notebook'; import Notebook from '~icons/mdi/notebook';
import ClipboardList from '~icons/mdi/clipboard-list';
import Image from '~icons/mdi/image';
import Star from '~icons/mdi/star'; import Star from '~icons/mdi/star';
import Attachment from '~icons/mdi/attachment'; import PlaneCar from '~icons/mdi/plane-car';
import PointSelectionModal from './PointSelectionModal.svelte'; import LinkVariant from '~icons/mdi/link-variant';
import Earth from '~icons/mdi/earth'; import Airplane from '~icons/mdi/airplane';
import TransportationCard from './TransportationCard.svelte';
onMount(async () => { onMount(async () => {
modal = document.getElementById('my_modal_1') as HTMLDialogElement; modal = document.getElementById('my_modal_1') as HTMLDialogElement;
@ -99,7 +94,7 @@
class="input input-bordered w-full max-w-xs mt-1" class="input input-bordered w-full max-w-xs mt-1"
/> />
<div class="mb-2"> <div class="mb-2">
<label for="type">Type <Calendar class="inline-block mb-1 w-6 h-6" /></label><br /> <label for="type">Type <PlaneCar class="inline-block mb-1 w-6 h-6" /></label><br />
<select <select
class="select select-bordered w-full max-w-xs" class="select select-bordered w-full max-w-xs"
name="type" name="type"
@ -164,7 +159,7 @@
/> />
</div> </div>
<div class="mb-2"> <div class="mb-2">
<label for="rating">Link <Star class="inline-block mb-1 w-6 h-6" /></label><br /> <label for="rating">Link <LinkVariant class="inline-block mb-1 w-6 h-6" /></label><br />
<input <input
type="url" type="url"
id="link" id="link"
@ -173,22 +168,11 @@
class="input input-bordered w-full max-w-xs mt-1" class="input input-bordered w-full max-w-xs mt-1"
/> />
</div> </div>
<div class="mb-2">
<label for="rating">Rating <Star class="inline-block mb-1 w-6 h-6" /></label><br />
<input
type="number"
max="5"
min="0"
id="rating"
name="rating"
bind:value={transportationToEdit.rating}
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
{#if transportationToEdit.type == 'plane'} {#if transportationToEdit.type == 'plane'}
<div class="mb-2"> <div class="mb-2">
<label for="flight_number" <label for="flight_number"
>Flight Number <Star class="inline-block mb-1 w-6 h-6" /></label >Flight Number <Airplane class="inline-block mb-1 w-6 h-6" /></label
><br /> ><br />
<input <input
type="text" type="text"
@ -200,8 +184,8 @@
</div> </div>
{/if} {/if}
<div class="mb-2"> <div class="mb-2">
<label for="rating">From Location <Star class="inline-block mb-1 w-6 h-6" /></label><br <label for="rating">From Location <MapMarker class="inline-block mb-1 w-6 h-6" /></label
/> ><br />
<input <input
type="text" type="text"
id="from_location" id="from_location"
@ -211,7 +195,8 @@
/> />
</div> </div>
<div class="mb-2"> <div class="mb-2">
<label for="rating">To Location <Star class="inline-block mb-1 w-6 h-6" /></label><br /> <label for="rating">To Location <MapMarker class="inline-block mb-1 w-6 h-6" /></label
><br />
<input <input
type="text" type="text"
id="to_location" id="to_location"

View file

@ -0,0 +1,232 @@
<script lang="ts">
// let newTransportation: Transportation = {
// id:NaN,
// user_id: NaN,
// type: '',
// name: '',
// description: null,
// rating: NaN,
// link: null,
// date: null,
// flight_number: null,
// from_location: null,
// to_location: null,
// is_public: false,
// collection: null,
// created_at: '',
// updated_at: ''
// };
import { createEventDispatcher } from 'svelte';
import type { Collection, Transportation } from '$lib/types';
const dispatch = createEventDispatcher();
import { onMount } from 'svelte';
import { addToast } from '$lib/toasts';
let modal: HTMLDialogElement;
export let collection: Collection;
import MapMarker from '~icons/mdi/map-marker';
import Calendar from '~icons/mdi/calendar';
import Notebook from '~icons/mdi/notebook';
import Star from '~icons/mdi/star';
import PlaneCar from '~icons/mdi/plane-car';
import LinkVariant from '~icons/mdi/link-variant';
import Airplane from '~icons/mdi/airplane';
let type: string = '';
onMount(async () => {
modal = document.getElementById('my_modal_1') as HTMLDialogElement;
if (modal) {
modal.showModal();
}
});
// if (newTransportation.date) {
// newTransportation.date = newTransportation.date.slice(0, 19);
// }
function close() {
dispatch('close');
}
function handleKeydown(event: KeyboardEvent) {
if (event.key === 'Escape') {
close();
}
}
async function handleSubmit(event: Event) {
event.preventDefault();
const form = event.target as HTMLFormElement;
const formData = new FormData(form);
const response = await fetch(`/api/transportations/`, {
method: 'POST',
body: formData
});
if (response.ok) {
const result = await response.json();
addToast('success', 'Transportation added successfully!');
dispatch('add', result);
close();
} else {
addToast('error', 'Error editing transportation');
}
}
</script>
<dialog id="my_modal_1" class="modal">
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
<h3 class="font-bold text-lg">New Transportation</h3>
<div
class="modal-action items-center"
style="display: flex; flex-direction: column; align-items: center; width: 100%;"
>
<form method="post" style="width: 100%;" on:submit={handleSubmit}>
<div class="mb-2">
<!-- <input
type="text"
id="id"
name="id"
hidden
readonly
bind:value={newTransportation.id}
class="input input-bordered w-full max-w-xs mt-1"
/> -->
<input
type="text"
id="collection"
name="collection"
hidden
readonly
bind:value={collection.id}
class="input input-bordered w-full max-w-xs mt-1"
/>
<input
type="text"
id="is_public"
name="is_public"
hidden
readonly
bind:value={collection.is_public}
class="input input-bordered w-full max-w-xs mt-1"
/>
<div class="mb-2">
<label for="type">Type <PlaneCar class="inline-block mb-1 w-6 h-6" /></label><br />
<select
class="select select-bordered w-full max-w-xs"
name="type"
id="type"
bind:value={type}
>
<option disabled selected>Transport Type</option>
<option value="car">Car</option>
<option value="plane">Plane</option>
<option value="train">Train</option>
<option value="bus">Bus</option>
<option value="boat">Boat</option>
<option value="bike">Bike</option>
<option value="walking">Walking</option>
<option value="other">Other</option>
</select>
</div>
<label for="name">Name</label><br />
<input
type="text"
name="name"
id="name"
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
<div class="mb-2">
<label for="date">Description <Notebook class="inline-block -mt-1 mb-1 w-6 h-6" /></label
><br />
<div class="flex">
<input
type="text"
id="description"
name="description"
class="input input-bordered w-full max-w-xs mt-1 mb-2"
/>
</div>
<div class="mb-2">
<label for="start_date"
>Date & Time <Calendar class="inline-block mb-1 w-6 h-6" /></label
><br />
<input
type="datetime-local"
id="date"
name="date"
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
<div class="mb-2">
<label for="rating">Rating <Star class="inline-block mb-1 w-6 h-6" /></label><br />
<input
type="number"
max="5"
min="0"
id="rating"
name="rating"
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
<div class="mb-2">
<label for="rating">Link <LinkVariant class="inline-block mb-1 w-6 h-6" /></label><br />
<input
type="url"
id="link"
name="link"
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
{#if type == 'plane'}
<div class="mb-2">
<label for="flight_number"
>Flight Number <Airplane class="inline-block mb-1 w-6 h-6" /></label
><br />
<input
type="text"
id="flight_number"
name="flight_number"
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
{/if}
<div class="mb-2">
<label for="rating">From Location <MapMarker class="inline-block mb-1 w-6 h-6" /></label
><br />
<input
type="text"
id="from_location"
name="from_location"
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
<div class="mb-2">
<label for="rating">To Location <MapMarker class="inline-block mb-1 w-6 h-6" /></label
><br />
<input
type="text"
id="to_location"
name="to_location"
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
</div>
<button type="submit" class="btn btn-primary mr-4 mt-4">Edit</button>
<!-- if there is a button in form, it will close the modal -->
<button class="btn mt-4" on:click={close}>Close</button>
</form>
<div class="flex items-center justify-center flex-wrap gap-4 mt-4"></div>
</div>
</div>
</dialog>

View file

@ -88,7 +88,7 @@ export type OpenStreetMapPlace = {
export type Transportation = { export type Transportation = {
id: number; id: number;
user_id: User; user_id: number;
type: string; type: string;
name: string; name: string;
description: string | null; description: string | null;

View file

@ -14,6 +14,7 @@
import { DefaultMarker, MapLibre, Popup } from 'svelte-maplibre'; import { DefaultMarker, MapLibre, Popup } from 'svelte-maplibre';
import TransportationCard from '$lib/components/TransportationCard.svelte'; import TransportationCard from '$lib/components/TransportationCard.svelte';
import EditTransportation from '$lib/components/EditTransportation.svelte'; import EditTransportation from '$lib/components/EditTransportation.svelte';
import NewTransportation from '$lib/components/NewTransportation.svelte';
export let data: PageData; export let data: PageData;
@ -32,6 +33,7 @@
let notFound: boolean = false; let notFound: boolean = false;
let isShowingLinkModal: boolean = false; let isShowingLinkModal: boolean = false;
let isShowingCreateModal: boolean = false; let isShowingCreateModal: boolean = false;
let isShowingTransportationModal: boolean = false;
onMount(() => { onMount(() => {
if (data.props.adventure) { if (data.props.adventure) {
@ -190,6 +192,17 @@
/> />
{/if} {/if}
{#if isShowingTransportationModal}
<NewTransportation
on:close={() => (isShowingTransportationModal = false)}
on:add={(event) => {
transportations = [event.detail, ...transportations];
isShowingTransportationModal = false;
}}
{collection}
/>
{/if}
{#if notFound} {#if notFound}
<div <div
class="flex min-h-[100dvh] flex-col items-center justify-center bg-background px-4 py-12 sm:px-6 lg:px-8 -mt-20" class="flex min-h-[100dvh] flex-col items-center justify-center bg-background px-4 py-12 sm:px-6 lg:px-8 -mt-20"
@ -276,6 +289,15 @@
> >
Dining</button Dining</button
> >
<button
class="btn btn-primary"
on:click={() => {
isShowingTransportationModal = true;
newType = '';
}}
>
Transportation</button
>
<!-- <button <!-- <button
class="btn btn-primary" class="btn btn-primary"