Skip to content

Commit

Permalink
Implemented initial Aircraft entry page. Component updates and fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
knicholson32 committed Jan 10, 2024
1 parent 1dc379f commit d856527
Show file tree
Hide file tree
Showing 29 changed files with 713 additions and 245 deletions.
45 changes: 23 additions & 22 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,29 @@ model AircraftType {
@@map("aircraft-types")
}

model Aircraft {
id String @id
registration String @unique
aircraftTypeId String
type AircraftType @relation(fields: [aircraftTypeId], references: [id], onDelete: Restrict)
year Int?
serial String?
simulator Boolean @default(false)
complex Boolean?
taa Boolean?
highPerformance Boolean?
pressurized Boolean?
notes String?
image Image? @relation(fields: [imageId], references: [id], onDelete: Restrict)
imageId String? @unique
legs Leg[]
@@map("aircraft")
}

model Image {
id String @unique
original Bytes
Expand All @@ -317,28 +340,6 @@ model Image {
@@map("images")
}

model Aircraft {
registration String @id
aircraftTypeId String
type AircraftType @relation(fields: [aircraftTypeId], references: [id], onDelete: Restrict)
year Int?
serial String?
simulator Boolean @default(false)
complex Boolean?
taa Boolean?
highPerformance Boolean?
pressurized Boolean?
notes String?
image Image? @relation(fields: [imageId], references: [id], onDelete: Restrict)
imageId String? @unique
legs Leg[]
@@map("aircraft")
}

model Airport {
id String @id
timezone String
Expand Down
18 changes: 18 additions & 0 deletions src/lib/components/decorations/Stats.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="ts">
type Value = {
title: string,
value: string
}[]
export let values: Value
</script>

<div>
<dl class="my-4 mx-4 grid grid-cols-1 gap-5 sm:grid-cols-3">
{#each values as v (v.title)}
<div class="overflow-hidden rounded-lg bg-white px-4 py-5 shadow sm:p-6">
<dt class="truncate text-sm font-medium text-gray-500">{v.title}</dt>
<dd class="mt-1 text-3xl font-semibold tracking-tight text-gray-900">{v.value}</dd>
</div>
{/each}
</dl>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
if (confirm('This aircraft does not exist. Do you want to create it?')) {
// Save it!
goto('/aircraft/new?reg=' + v + '&ref=' + $page.url.pathname);
goto('/aircraft/entry/new?reg=' + v + '&ref=' + $page.url.pathname + '&active=form');
}
// if (v.length > 4 || v.length < 3) {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import hi from "date-fns/locale/hi";
import { onMount } from "svelte";
export let initialImageId: string | null = null;
export let initialImageId: string | null = 'unset';
export let name: string;
export let disabled: boolean = false;
export let maxMB = 10;
Expand All @@ -26,7 +26,7 @@
// is immortally cleared.
const initialImageIDChange = () => {
_initialImageId = initialImageId;
initialImageId = null;
initialImageId = 'unset';
}
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<script lang="ts">
import type { API } from "$lib/types";
import { onMount } from "svelte";
import { onMount } from "svelte";
import Frame from "./Frame.svelte";
import { browser } from "$app/environment";
import id from "date-fns/locale/id";
export let value: string | null = null;
export let updatedValue: string | null = null;
export let action: string = '?/default';
export let form: null | API.Form.Type = null
export let name: string;
Expand All @@ -29,6 +30,7 @@
}
}
lastValue = input.value;
updatedValue = lastValue;
if (uid !== null) {
localStorage.setItem(uid + '.' + name, lastValue);
localStorage.setItem(uid + '.unsaved', 'true');
Expand All @@ -50,7 +52,10 @@
const checkLocalStorage = () => {
if (!browser) return;
const savedValue = localStorage.getItem(uid + '.' + name);
if (savedValue !== null) value = savedValue;
if (savedValue !== null) {
value = savedValue;
updatedValue = value;
}
}
/**
Expand All @@ -61,6 +66,7 @@
if (uid === null) return;
if (e.key !== uid + '.' + name || e.newValue === null) return;
value = e.newValue;
updatedValue = lastValue;
}
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import Frame from './Frame.svelte';
export let value: string | null = '';
export let updatedValue: string | null = null;
export let options: ({ title: string; value: string; unset?: boolean } | string)[];
export let mono = true;
export let error = '';
Expand All @@ -22,8 +23,11 @@
const _update = () => {
if (uid !== null) {
if (value === null) localStorage.removeItem(uid + '.' + name);
else {
if (value === null) {
updatedValue = null;
localStorage.removeItem(uid + '.' + name);
} else {
updatedValue = value;
localStorage.setItem(uid + '.' + name, value);
localStorage.setItem(uid + '.unsaved', 'true');
}
Expand All @@ -46,7 +50,10 @@
const checkLocalStorage = () => {
if (!browser) return;
const savedValue = localStorage.getItem(uid + '.' + name);
if (savedValue !== null) value = savedValue;
if (savedValue !== null) {
value = savedValue;
updatedValue = value;
}
}
/**
Expand All @@ -57,7 +64,7 @@
if (uid === null) return;
if (e.key !== uid + '.' + name || e.newValue === null) return;
value = e.newValue;
updatedValue = value;
}
/**
Expand All @@ -69,6 +76,8 @@
if (uid !== null) checkLocalStorage();
}
$: { console.log(updatedValue) };
/**
* Attach a handler to listen for the storage event, which is emitted when
* local storage changes. Remove if off mount.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import Frame from "./Frame.svelte";
export let value: boolean = false;
export let updatedValue: boolean | null = null;
export let name: string;
export let title: string;
export let disabled: boolean = false;
Expand All @@ -16,6 +17,7 @@
const _update = () => {
if (uid !== null) {
updatedValue = value;
localStorage.setItem(uid + '.' + name, value ? 'true' : 'false');
localStorage.setItem(uid + '.unsaved', 'true');
}
Expand Down Expand Up @@ -45,6 +47,7 @@
if (uid === null) return;
if (e.key !== uid + '.' + name || e.newValue === null || (e.newValue !== 'true' && e.newValue !== 'false')) return;
value = e.newValue === 'true';
updatedValue = value;
}
/**
Expand Down
65 changes: 65 additions & 0 deletions src/lib/components/entry/TextField.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<script lang="ts">
import { browser } from "$app/environment";
import { onMount } from "svelte";
export let name: string;
export let disabled: boolean = false;
export let placeholder = 'Enter comments';
export let update: () => void = () => {};
export let required: boolean = false;
export let value: string | null = null;
const _update = () => {
if (uid !== null) {
localStorage.setItem(uid + '.' + name, value ?? '');
localStorage.setItem(uid + '.unsaved', 'true');
}
update();
}
// ----------------------------------------------------------------------------
// Local Storage Support
// ----------------------------------------------------------------------------
export let uid: string | null = null;
/**
* Check local storage. If it exists and is not null, use that value
*/
const checkLocalStorage = () => {
if (!browser) return;
const savedValue = localStorage.getItem(uid + '.' + name);
if (savedValue !== null) value = savedValue;
}
/**
* Check for a storage update. If the update matches the key and is not null,
* use that value
*/
const checkStorageUpdate = (e: StorageEvent) => {
if (uid === null) return;
if (e.key !== uid + '.' + name || e.newValue === null) return;
value = e.newValue;
}
/**
* If uid or name changes, the entry element has been re-assigned. Check local
* storage and assign if required
*/
$:{
name;
if (uid !== null) checkLocalStorage();
}
/**
* Attach a handler to listen for the storage event, which is emitted when
* local storage changes. Remove if off mount.
*/
onMount(() => {
window.addEventListener('storage', checkStorageUpdate)
return () => window.removeEventListener('storage', checkStorageUpdate)
});
</script>

<li class="w-full relative inline-flex items-center px-3 py-1 {disabled ? 'cursor-not-allowed bg-gray-50 text-gray-500' : ''}">
<textarea {required} bind:value={value} on:input={_update} disabled={disabled ? true : undefined} {placeholder} {name} class="m-0 p-0 text-sm font-medium w-full border-0 ring-0 outline-none bg-transparent focus-within:outline-none focus-within:ring-0 placeholder:text-gray-400 placeholder:text-xs disabled:cursor-not-allowed disabled:text-gray-500" rows="5"/>
</li>
File renamed without changes.
File renamed without changes.
24 changes: 24 additions & 0 deletions src/lib/components/menuForm/BlankMenu.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
export let href: string;
export let title: string;
export let subtitle: string;
export let buttonText: string
</script>

<div class="absolute top-0 bottom-24 text-center w-full flex flex-col justify-center items-center">
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" />
</svg>
<h3 class="mt-2 text-sm font-semibold text-gray-900">{title}</h3>
<p class="mt-1 text-sm text-gray-500">{subtitle}</p>
<div class="mt-6">
<a href={href} type="button" class="inline-flex items-center rounded-md bg-sky-500 px-3 py-2 text-sm font-semibold text-white shadow-sm betterhover:hover:bg-sky-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-500">
<svg class="-ml-0.5 mr-1.5 h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z" />
</svg>
{buttonText}
</a>
</div>
</div>
8 changes: 8 additions & 0 deletions src/lib/components/menuForm/FormHeader.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script lang="ts">
export let title: string;
</script>

<div class="w-full bg-sky-900 text-white">
<div class="text-xl w-full text-left font-bold font-mono px-4 pt-2">{title}</div>
<slot/>
</div>
69 changes: 69 additions & 0 deletions src/lib/components/menuForm/Link.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<script lang="ts">
import { page } from "$app/stores";
import icons from "../icons";
export let href: string;
export let text: string;
export let icon: string | null = null;
export let selected = false;
export let type: 'left' | 'right' = 'left';
export let theme: 'default' | 'FormHeader' = 'default';
</script>

{#if theme === 'default'}
{#if type === 'left'}
<a href={href} class="hidden md:flex border-b select-none h-11 relative flex-row justify-left items-center gap-2 pl-2 pr-6 py-2 betterhover:hover:bg-gray-200 betterhover:hover:text-black">
<div class="h-7 w-12 flex-shrink-0 overflow-hidden text-ellipsis whitespace-nowrap flex items-center justify-center">
<svg class="h-4 w-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" >
{@html icons.chevronLeft}
</svg>
</div>
<div class="flex flex-col gap-1 overflow-hidden flex-initial">
<div class="uppercase font-bold text-xs overflow-hidden whitespace-nowrap text-ellipsis">{text}</div>
</div>
</a>
{:else}
<a href={href} class="relative border-b select-none flex flex-row justify-left items-center gap-2 pl-2 pr-6 py-2 {selected ? 'bg-gray-200' : 'betterhover:hover:bg-gray-200 betterhover:hover:text-black'}">
{#if icon !== null}
<div class="h-7 w-12 flex-shrink-0 overflow-hidden text-ellipsis whitespace-nowrap flex items-center justify-center">
<div class="h-7 w-7 flex-shrink-0 rounded-full bg-gray-600 text-black uppercase font-mono text-xs overflow-hidden text-ellipsis whitespace-nowrap flex items-center justify-center">
<svg class="h-4 w-4 shrink-0 text-white" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" >
{@html icon}
</svg>
</div>
</div>
{/if}
<div class="flex flex-col gap-1 overflow-hidden flex-initial">
<div class="uppercase font-bold text-xs overflow-hidden whitespace-nowrap text-ellipsis">{text}</div>
</div>
<div class="absolute right-1">
<svg class="h-4 w-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" >
{@html icons.chevronRight}
</svg>
</div>
</a>
{/if}
{:else}
<a href={href} class="border-t border-sky-800 relative select-none flex flex-row justify-left items-center gap-2 pl-2 pr-6 py-2 {selected ? 'bg-sky-800' : 'betterhover:hover:bg-sky-800'}">
<div class="h-7 w-12 flex-shrink-0 overflow-hidden text-ellipsis whitespace-nowrap flex items-center justify-center">
<div class="h-7 w-7 flex-shrink-0 rounded-full bg-sky-600 text-black uppercase font-mono text-xs overflow-hidden text-ellipsis whitespace-nowrap flex items-center justify-center">
<svg class="h-4 w-4 shrink-0 text-white" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" >
{@html icon}
</svg>
</div>
</div>
<div class="flex flex-col gap-1 overflow-hidden flex-initial">
<div class="uppercase font-bold text-xs overflow-hidden whitespace-nowrap text-ellipsis">{text}</div>
</div>
<div class="absolute right-1">
<svg class="h-4 w-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" >
{@html icons.chevronRight}
</svg>
</div>
</a>
{/if}
Loading

0 comments on commit d856527

Please sign in to comment.