aboutsummaryrefslogtreecommitdiffstats
path: root/code/app/src/routes/(main)/(app)
diff options
context:
space:
mode:
authorivarlovlie <git@ivarlovlie.no>2022-10-15 10:40:58 +0200
committerivarlovlie <git@ivarlovlie.no>2022-10-15 10:40:58 +0200
commit4b42c5235482fe0d3811b4e2936614c79e20d970 (patch)
tree90a69742caebd8281a48be27ace0297554e59e95 /code/app/src/routes/(main)/(app)
parent0825788e86809f10bb83d664084328dff0b47146 (diff)
downloadgreatoffice-4b42c5235482fe0d3811b4e2936614c79e20d970.tar.xz
greatoffice-4b42c5235482fe0d3811b4e2936614c79e20d970.zip
feat: !WIP start of create project page
Diffstat (limited to 'code/app/src/routes/(main)/(app)')
-rw-r--r--code/app/src/routes/(main)/(app)/+layout.svelte4
-rw-r--r--code/app/src/routes/(main)/(app)/projects/+page.svelte150
-rw-r--r--code/app/src/routes/(main)/(app)/projects/new/+page.svelte43
3 files changed, 119 insertions, 78 deletions
diff --git a/code/app/src/routes/(main)/(app)/+layout.svelte b/code/app/src/routes/(main)/(app)/+layout.svelte
index 0be6ff3..ad8f3ce 100644
--- a/code/app/src/routes/(main)/(app)/+layout.svelte
+++ b/code/app/src/routes/(main)/(app)/+layout.svelte
@@ -12,7 +12,7 @@
} from "$lib/components/icons";
import { Dialog, Menu, MenuButton, MenuItem, MenuItems, Transition, TransitionChild, TransitionRoot } from "@rgossiaux/svelte-headlessui";
import { DialogPanel } from "@developermuch/dev-svelte-headlessui";
- import type { ISession } from "$lib/models/ISession";
+ import type { ISession } from "$lib/models/internal/ISession";
import { Input } from "$lib/components";
import { end_session } from "$lib/session";
import { goto } from "$app/navigation";
@@ -290,7 +290,7 @@
</div>
</div>
</div>
- <main class="flex-1">
+ <main class="flex-1 p-3">
<slot />
</main>
</div>
diff --git a/code/app/src/routes/(main)/(app)/projects/+page.svelte b/code/app/src/routes/(main)/(app)/projects/+page.svelte
index ceb08b4..55e9372 100644
--- a/code/app/src/routes/(main)/(app)/projects/+page.svelte
+++ b/code/app/src/routes/(main)/(app)/projects/+page.svelte
@@ -21,7 +21,7 @@
tempProjects.push({
id: crypto.randomUUID(),
name: faker.word.preposition(),
- start: Temporal.Now.plainDateISO(),
+ start: Temporal.Now.plainDateISO().toLocaleString(),
description: faker.lorem.words(3),
members: [],
status: ProjectStatus.IDLE,
@@ -52,85 +52,83 @@
const { filterValue } = pluginStates.filter;
</script>
-<div class="py-2 px-5">
- <div class="sm:flex sm:items-center">
- <div class="sm:flex-auto">
- <h1 class="text-xl font-semibold text-gray-900">Projects</h1>
- <p class="mt-2 text-sm text-gray-700">A list of all the projects in your organsation.</p>
- </div>
- <div class="mt-4 sm:mt-0 sm:ml-16 inline-flex gap-1 sm:flex-none">
- <Input icon={MagnifyingGlassIcon} placeholder="Search" bind:value={$filterValue} />
- <Button text="Create project" />
- </div>
+<div class="sm:flex sm:items-center">
+ <div class="sm:flex-auto">
+ <h1 class="text-xl font-semibold text-gray-900">Projects</h1>
+ <p class="mt-2 text-sm text-gray-700">A list of all the projects in your organsation.</p>
</div>
- <div class="-mx-2 mt-6 rounded-md shadow overflow-auto max-h-[80vh] sm:-mx-6 md:mx-0">
- <table {...$tableAttrs} class="min-w-full divide-y divide-gray-300">
- <thead class="bg-gray-50">
- {#each $headerRows as headerRow (headerRow.id)}
- <Subscribe rowAttrs={headerRow.attrs()} let:rowAttrs>
- <tr {...rowAttrs} class="shadow-sm">
- {#each headerRow.cells as cell (cell.id)}
- <Subscribe attrs={cell.attrs()} let:attrs props={cell.props()} let:props>
- <th
- {...attrs}
- scope="col"
- class="sticky top-0 bg-gray-50 bg-opacity-100 whitespace-nowrap px-2 py-3.5 text-left text-sm font-semibold text-gray-900"
- >
- <div class="group inline-flex">
- <Render of={cell.render()} />
- <span
- on:click={props.sort.toggle}
- class="{props.sort.disabled
- ? 'bg-gray-200 text-gray-900 group-hover:bg-gray-300'
- : 'invisible text-gray-400 group-hover:visible group-focus:visible'}
+ <div class="mt-4 sm:mt-0 sm:ml-16 inline-flex gap-1 sm:flex-none">
+ <Input icon={MagnifyingGlassIcon} placeholder="Search" bind:value={$filterValue} />
+ <Button text="Create project" href="/projects/new" />
+ </div>
+</div>
+<div class="-mx-2 mt-6 rounded-md shadow overflow-auto max-h-[80vh] sm:-mx-6 md:mx-0">
+ <table {...$tableAttrs} class="min-w-full divide-y divide-gray-300">
+ <thead class="bg-gray-50">
+ {#each $headerRows as headerRow (headerRow.id)}
+ <Subscribe rowAttrs={headerRow.attrs()} let:rowAttrs>
+ <tr {...rowAttrs} class="shadow-sm">
+ {#each headerRow.cells as cell (cell.id)}
+ <Subscribe attrs={cell.attrs()} let:attrs props={cell.props()} let:props>
+ <th
+ {...attrs}
+ scope="col"
+ class="sticky top-0 bg-gray-50 bg-opacity-100 whitespace-nowrap px-2 py-3.5 text-left text-sm font-semibold text-gray-900"
+ >
+ <div class="group inline-flex">
+ <Render of={cell.render()} />
+ <span
+ on:click={props.sort.toggle}
+ class="{props.sort.disabled
+ ? 'bg-gray-200 text-gray-900 group-hover:bg-gray-300'
+ : 'invisible text-gray-400 group-hover:visible group-focus:visible'}
{props.sort.disabled ? '' : 'cursor-pointer'}
ml-2 flex-none rounded"
- >
- {#if props.sort.order === "asc"}
- <ChevronUpIcon />
- {:else if props.sort.order === "desc"}
- <ChevronDownIcon />
- {:else if !props.sort.disabled}
- <ChevronUpDownIcon />
- {/if}
- </span>
- {#if cell.id === "status"}
- <span class="invisible text-gray-400 cursor-pointer group-hover:visible group-focus:visible ml-2 flex-none rounded">
- <FunnelIcon />
- </span>
+ >
+ {#if props.sort.order === "asc"}
+ <ChevronUpIcon />
+ {:else if props.sort.order === "desc"}
+ <ChevronDownIcon />
+ {:else if !props.sort.disabled}
+ <ChevronUpDownIcon />
{/if}
- </div>
- </th>
- </Subscribe>
- {/each}
- </tr>
- </Subscribe>
- {/each}
- </thead>
- <tbody {...$tableBodyAttrs} class="divide-y divide-gray-200 bg-white">
- {#each $rows as row (row.id)}
- <Subscribe rowAttrs={row.attrs()} let:rowAttrs>
- <tr {...rowAttrs}>
- {#each row.cells as cell (cell.id)}
- {@const materialisedCell = cell.render()}
- <Subscribe attrs={cell.attrs()} let:attrs>
- <td {...attrs} class="whitespace-nowrap px-2 py-2 text-sm">
- {#if cell.id === "name"}
- <span class="link" title="Open project" on:click={() => goto_project(materialisedCell.toString())}>
- <Render of={materialisedCell} />
+ </span>
+ {#if cell.id === "status"}
+ <span class="invisible text-gray-400 cursor-pointer group-hover:visible group-focus:visible ml-2 flex-none rounded">
+ <FunnelIcon />
</span>
- {:else if cell.id === "status"}
- <ProjectStatusBadge status={materialisedCell.toString()} />
- {:else}
- <Render of={materialisedCell} />
{/if}
- </td>
- </Subscribe>
- {/each}
- </tr>
- </Subscribe>
- {/each}
- </tbody>
- </table>
- </div>
+ </div>
+ </th>
+ </Subscribe>
+ {/each}
+ </tr>
+ </Subscribe>
+ {/each}
+ </thead>
+ <tbody {...$tableBodyAttrs} class="divide-y divide-gray-200 bg-white">
+ {#each $rows as row (row.id)}
+ <Subscribe rowAttrs={row.attrs()} let:rowAttrs>
+ <tr {...rowAttrs}>
+ {#each row.cells as cell (cell.id)}
+ {@const materialisedCell = cell.render()}
+ <Subscribe attrs={cell.attrs()} let:attrs>
+ <td {...attrs} class="whitespace-nowrap px-2 py-2 text-sm">
+ {#if cell.id === "name"}
+ <span class="link" title="Open project" on:click={() => goto_project(materialisedCell.toString())}>
+ <Render of={materialisedCell} />
+ </span>
+ {:else if cell.id === "status"}
+ <ProjectStatusBadge status={materialisedCell.toString()} />
+ {:else}
+ <Render of={materialisedCell} />
+ {/if}
+ </td>
+ </Subscribe>
+ {/each}
+ </tr>
+ </Subscribe>
+ {/each}
+ </tbody>
+ </table>
</div>
diff --git a/code/app/src/routes/(main)/(app)/projects/new/+page.svelte b/code/app/src/routes/(main)/(app)/projects/new/+page.svelte
new file mode 100644
index 0000000..4c453dc
--- /dev/null
+++ b/code/app/src/routes/(main)/(app)/projects/new/+page.svelte
@@ -0,0 +1,43 @@
+<script lang="ts">
+ import { useSWR } from "sswr";
+ import { Input, TextArea } from "$lib/components";
+ import type { ProjectMember } from "$lib/models/projects/ProjectMember";
+
+ const formFields = {
+ name: {
+ value: "",
+ error: "",
+ },
+ description: {
+ value: "",
+ error: "",
+ },
+ start: {
+ value: "",
+ error: "",
+ },
+ stop: {
+ value: "",
+ error: "",
+ },
+ members: {
+ value: [] as Array<ProjectMember>,
+ error: "",
+ },
+ clear() {},
+ };
+ async function submit(event: Event) {
+ alert("Submitted");
+ }
+ const { data: members } = useSWR("projectMembers");
+</script>
+
+<h1>Create a new project</h1>
+<form on:submit|preventDefault={submit} class="max-w-md flex flex-col gap-2">
+ <Input label="Name" bind:value={formFields.name.value} errorText={formFields.name.error} required />
+ <TextArea label="Description" bind:value={formFields.description.value} errorText={formFields.description.error} />
+ <section class="grid grid-flow-row sm:grid-flow-col gap-2">
+ <Input type="date" label="Start" bind:value={formFields.start.value} errorText={formFields.start.error} />
+ <Input type="date" label="Stop" bind:value={formFields.stop.value} errorText={formFields.stop.error} />
+ </section>
+</form>