mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-24 07:19:36 +02:00
add transportation
This commit is contained in:
parent
61c3d23efa
commit
6155d531ab
5 changed files with 267 additions and 28 deletions
|
@ -30,7 +30,7 @@ class TransportationSerializer(serializers.ModelSerializer):
|
|||
fields = [
|
||||
'id', 'user_id', 'type', 'name', 'description', 'rating',
|
||||
'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']
|
||||
|
||||
|
|
|
@ -11,18 +11,13 @@
|
|||
|
||||
let originalName = transportationToEdit.name;
|
||||
|
||||
let isPointModalOpen: boolean = false;
|
||||
|
||||
import MapMarker from '~icons/mdi/map-marker';
|
||||
import Calendar from '~icons/mdi/calendar';
|
||||
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 Attachment from '~icons/mdi/attachment';
|
||||
import PointSelectionModal from './PointSelectionModal.svelte';
|
||||
import Earth from '~icons/mdi/earth';
|
||||
import TransportationCard from './TransportationCard.svelte';
|
||||
import PlaneCar from '~icons/mdi/plane-car';
|
||||
import LinkVariant from '~icons/mdi/link-variant';
|
||||
import Airplane from '~icons/mdi/airplane';
|
||||
|
||||
onMount(async () => {
|
||||
modal = document.getElementById('my_modal_1') as HTMLDialogElement;
|
||||
|
@ -99,7 +94,7 @@
|
|||
class="input input-bordered w-full max-w-xs mt-1"
|
||||
/>
|
||||
<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
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
name="type"
|
||||
|
@ -164,7 +159,7 @@
|
|||
/>
|
||||
</div>
|
||||
<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
|
||||
type="url"
|
||||
id="link"
|
||||
|
@ -173,22 +168,11 @@
|
|||
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"
|
||||
bind:value={transportationToEdit.rating}
|
||||
class="input input-bordered w-full max-w-xs mt-1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if transportationToEdit.type == 'plane'}
|
||||
<div class="mb-2">
|
||||
<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 />
|
||||
<input
|
||||
type="text"
|
||||
|
@ -200,8 +184,8 @@
|
|||
</div>
|
||||
{/if}
|
||||
<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
|
||||
type="text"
|
||||
id="from_location"
|
||||
|
@ -211,7 +195,8 @@
|
|||
/>
|
||||
</div>
|
||||
<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
|
||||
type="text"
|
||||
id="to_location"
|
||||
|
|
232
frontend/src/lib/components/NewTransportation.svelte
Normal file
232
frontend/src/lib/components/NewTransportation.svelte
Normal 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>
|
|
@ -88,7 +88,7 @@ export type OpenStreetMapPlace = {
|
|||
|
||||
export type Transportation = {
|
||||
id: number;
|
||||
user_id: User;
|
||||
user_id: number;
|
||||
type: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
import { DefaultMarker, MapLibre, Popup } from 'svelte-maplibre';
|
||||
import TransportationCard from '$lib/components/TransportationCard.svelte';
|
||||
import EditTransportation from '$lib/components/EditTransportation.svelte';
|
||||
import NewTransportation from '$lib/components/NewTransportation.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -32,6 +33,7 @@
|
|||
let notFound: boolean = false;
|
||||
let isShowingLinkModal: boolean = false;
|
||||
let isShowingCreateModal: boolean = false;
|
||||
let isShowingTransportationModal: boolean = false;
|
||||
|
||||
onMount(() => {
|
||||
if (data.props.adventure) {
|
||||
|
@ -190,6 +192,17 @@
|
|||
/>
|
||||
{/if}
|
||||
|
||||
{#if isShowingTransportationModal}
|
||||
<NewTransportation
|
||||
on:close={() => (isShowingTransportationModal = false)}
|
||||
on:add={(event) => {
|
||||
transportations = [event.detail, ...transportations];
|
||||
isShowingTransportationModal = false;
|
||||
}}
|
||||
{collection}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if notFound}
|
||||
<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"
|
||||
|
@ -276,6 +289,15 @@
|
|||
>
|
||||
Dining</button
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
on:click={() => {
|
||||
isShowingTransportationModal = true;
|
||||
newType = '';
|
||||
}}
|
||||
>
|
||||
Transportation</button
|
||||
>
|
||||
|
||||
<!-- <button
|
||||
class="btn btn-primary"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue