aboutsummaryrefslogtreecommitdiffstats
path: root/code/app/src/routes
diff options
context:
space:
mode:
Diffstat (limited to 'code/app/src/routes')
-rw-r--r--code/app/src/routes/(main)/(app)/projects/+page.svelte11
-rw-r--r--code/app/src/routes/(main)/(app)/projects/create/+page.svelte (renamed from code/app/src/routes/(main)/(app)/projects/new/+page.svelte)14
-rw-r--r--code/app/src/routes/(main)/(app)/settings/+page.svelte199
-rw-r--r--code/app/src/routes/(main)/(public)/reset-password/+page.svelte2
-rw-r--r--code/app/src/routes/(main)/(public)/reset-password/[id]/+page.svelte2
-rw-r--r--code/app/src/routes/(main)/(public)/sign-in/+page.svelte4
-rw-r--r--code/app/src/routes/(main)/(public)/sign-in/index.ts11
-rw-r--r--code/app/src/routes/(main)/(public)/sign-up/+page.svelte4
-rw-r--r--code/app/src/routes/book/inputs/+page.svelte9
9 files changed, 238 insertions, 18 deletions
diff --git a/code/app/src/routes/(main)/(app)/projects/+page.svelte b/code/app/src/routes/(main)/(app)/projects/+page.svelte
index 55e9372..e39a886 100644
--- a/code/app/src/routes/(main)/(app)/projects/+page.svelte
+++ b/code/app/src/routes/(main)/(app)/projects/+page.svelte
@@ -20,7 +20,7 @@
while (i < 101) {
tempProjects.push({
id: crypto.randomUUID(),
- name: faker.word.preposition(),
+ name: faker.lorem.word(),
start: Temporal.Now.plainDateISO().toLocaleString(),
description: faker.lorem.words(3),
members: [],
@@ -31,7 +31,9 @@
projects.set(tempProjects);
});
- function goto_project(name: string) {
+ function on_open_project(event) {
+ if (event.code && (event.code !== "Enter" || event.code !== "Space")) return;
+ const name = event.target.innerText;
const projectId = $projects.find((p) => p.name === name).id;
goto("/projects/" + projectId);
}
@@ -59,7 +61,7 @@
</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" href="/projects/new" />
+ <Button text="Create project" href="/projects/create" />
</div>
</div>
<div class="-mx-2 mt-6 rounded-md shadow overflow-auto max-h-[80vh] sm:-mx-6 md:mx-0">
@@ -79,6 +81,7 @@
<Render of={cell.render()} />
<span
on:click={props.sort.toggle}
+ on:keypress={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'}
@@ -115,7 +118,7 @@
<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())}>
+ <span class="link" title="Open project" on:click={on_open_project} on:keypress={on_open_project}>
<Render of={materialisedCell} />
</span>
{:else if cell.id === "status"}
diff --git a/code/app/src/routes/(main)/(app)/projects/new/+page.svelte b/code/app/src/routes/(main)/(app)/projects/create/+page.svelte
index 4c453dc..2b5e7bc 100644
--- a/code/app/src/routes/(main)/(app)/projects/new/+page.svelte
+++ b/code/app/src/routes/(main)/(app)/projects/create/+page.svelte
@@ -1,7 +1,8 @@
<script lang="ts">
import { useSWR } from "sswr";
- import { Input, TextArea } from "$lib/components";
+ import { Input, TextArea, Combobox, Button } from "$lib/components";
import type { ProjectMember } from "$lib/models/projects/ProjectMember";
+ import LL from "$lib/i18n/i18n-svelte";
const formFields = {
name: {
@@ -40,4 +41,15 @@
<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>
+ <Combobox options={$members} label={$LL.app.members()}>
+ <svelte:fragment slot="no-records">
+ <h1>No members found</h1>
+ {#if !$members?.length}
+ <p>
+ <a href="/users/create" class="link">Click here</a> to create your first user
+ </p>
+ {/if}
+ </svelte:fragment>
+ </Combobox>
+ <Button text={$LL.submit()} />
</form>
diff --git a/code/app/src/routes/(main)/(app)/settings/+page.svelte b/code/app/src/routes/(main)/(app)/settings/+page.svelte
index ae6d403..1f0cc67 100644
--- a/code/app/src/routes/(main)/(app)/settings/+page.svelte
+++ b/code/app/src/routes/(main)/(app)/settings/+page.svelte
@@ -1,4 +1,201 @@
<script lang="ts">
+ import { Input, Button, Switch } from "$lib/components";
</script>
-<h1>Settings</h1>
+<div class="relative mx-auto max-w-4xl md:px-8 xl:px-0">
+ <div class="pt-10 pb-16">
+ <div class="px-4 sm:px-6 md:px-0">
+ <h1 class="text-3xl font-bold tracking-tight text-gray-900">Settings</h1>
+ </div>
+ <div class="px-4 sm:px-6 md:px-0">
+ <div class="py-6">
+ <!-- Tabs -->
+ <div class="lg:hidden">
+ <label for="selected-tab" class="sr-only">Select a tab</label>
+ <select
+ id="selected-tab"
+ name="selected-tab"
+ class="mt-1 block w-full rounded-md border-gray-300 py-2 pl-3 pr-10 text-base focus:border-purple-500 focus:outline-none focus:ring-purple-500 sm:text-sm"
+ >
+ <option selected>General</option>
+
+ <option>Password</option>
+
+ <option>Notifications</option>
+
+ <option>Plan</option>
+
+ <option>Billing</option>
+
+ <option>Team Members</option>
+ </select>
+ </div>
+ <div class="hidden lg:block">
+ <div class="border-b border-gray-200">
+ <nav class="-mb-px flex space-x-8">
+ <!-- Current: "border-purple-500 text-purple-600", Default: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700" -->
+ <a href="#" class="border-purple-500 text-purple-600 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
+ >General</a
+ >
+
+ <a
+ href="#"
+ class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
+ >Password</a
+ >
+
+ <a
+ href="#"
+ class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
+ >Notifications</a
+ >
+
+ <a
+ href="#"
+ class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
+ >Plan</a
+ >
+
+ <a
+ href="#"
+ class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
+ >Billing</a
+ >
+
+ <a
+ href="#"
+ class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
+ >Team Members</a
+ >
+ </nav>
+ </div>
+ </div>
+
+ <!-- Description list with inline editing -->
+ <div class="mt-10 divide-y divide-gray-200">
+ <div class="space-y-1">
+ <h3 class="text-lg font-medium leading-6 text-gray-900">Profile</h3>
+ <p class="max-w-2xl text-sm text-gray-500">
+ This information will be displayed publicly so be careful what you share.
+ </p>
+ </div>
+ <div class="mt-6">
+ <dl class="divide-y divide-gray-200">
+ <div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5">
+ <dt class="text-sm font-medium text-gray-500">Name</dt>
+ <dd class="mt-1 flex text-sm text-gray-900 sm:col-span-2 sm:mt-0">
+ <span class="flex-grow">Chelsea Hagon</span>
+ <span class="ml-4 flex-shrink-0">
+ <button
+ type="button"
+ class="rounded-md bg-white font-medium text-purple-600 hover:text-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
+ >Update</button
+ >
+ </span>
+ </dd>
+ </div>
+ <div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:pt-5">
+ <dt class="text-sm font-medium text-gray-500">Photo</dt>
+ <dd class="mt-1 flex text-sm text-gray-900 sm:col-span-2 sm:mt-0">
+ <span class="flex-grow">
+ <img
+ class="h-8 w-8 rounded-full"
+ src="https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
+ alt=""
+ />
+ </span>
+ <span class="ml-4 flex flex-shrink-0 items-start space-x-4">
+ <button
+ type="button"
+ class="rounded-md bg-white font-medium text-purple-600 hover:text-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
+ >Update</button
+ >
+ <span class="text-gray-300" aria-hidden="true">|</span>
+ <button
+ type="button"
+ class="rounded-md bg-white font-medium text-purple-600 hover:text-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
+ >Remove</button
+ >
+ </span>
+ </dd>
+ </div>
+ <div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:pt-5">
+ <dt class="text-sm font-medium text-gray-500">Email</dt>
+ <dd class="mt-1 flex text-sm text-gray-900 sm:col-span-2 sm:mt-0">
+ <span class="flex-grow">chelsea.hagon@example.com</span>
+ <span class="ml-4 flex-shrink-0">
+ <button
+ type="button"
+ class="rounded-md bg-white font-medium text-purple-600 hover:text-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
+ >Update</button
+ >
+ </span>
+ </dd>
+ </div>
+ <div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:border-b sm:border-gray-200 sm:py-5">
+ <dt class="text-sm font-medium text-gray-500">Job title</dt>
+ <dd class="mt-1 flex text-sm text-gray-900 sm:col-span-2 sm:mt-0">
+ <span class="flex-grow">Human Resources Manager</span>
+ <span class="ml-4 flex-shrink-0">
+ <button
+ type="button"
+ class="rounded-md bg-white font-medium text-purple-600 hover:text-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
+ >Update</button
+ >
+ </span>
+ </dd>
+ </div>
+ </dl>
+ </div>
+ </div>
+
+ <div class="mt-10 divide-y divide-gray-200">
+ <div class="space-y-1">
+ <h3 class="text-lg font-medium leading-6 text-gray-900">Account</h3>
+ <p class="max-w-2xl text-sm text-gray-500">Manage how information is displayed on your account.</p>
+ </div>
+ <div class="mt-6">
+ <dl class="divide-y divide-gray-200">
+ <div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5">
+ <dt class="text-sm font-medium text-gray-500">Language</dt>
+ <dd class="mt-1 flex text-sm text-gray-900 sm:col-span-2 sm:mt-0">
+ <span class="flex-grow">English</span>
+ <span class="ml-4 flex-shrink-0">
+ <button
+ type="button"
+ class="rounded-md bg-white font-medium text-purple-600 hover:text-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
+ >Update</button
+ >
+ </span>
+ </dd>
+ </div>
+ <div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:pt-5">
+ <dt class="text-sm font-medium text-gray-500">Date format</dt>
+ <dd class="mt-1 flex text-sm text-gray-900 sm:col-span-2 sm:mt-0">
+ <span class="flex-grow">DD-MM-YYYY</span>
+ <span class="ml-4 flex flex-shrink-0 items-start space-x-4">
+ <button
+ type="button"
+ class="rounded-md bg-white font-medium text-purple-600 hover:text-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
+ >Update</button
+ >
+ <span class="text-gray-300" aria-hidden="true">|</span>
+ <button
+ type="button"
+ class="rounded-md bg-white font-medium text-purple-600 hover:text-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
+ >Remove</button
+ >
+ </span>
+ </dd>
+ </div>
+ <div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:pt-5">
+ <dt class="text-sm font-medium text-gray-500" id="timezone-option-label">Automatic timezone</dt>
+ <Switch />
+ </div>
+ </dl>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/code/app/src/routes/(main)/(public)/reset-password/+page.svelte b/code/app/src/routes/(main)/(public)/reset-password/+page.svelte
index aa26892..32d4e21 100644
--- a/code/app/src/routes/(main)/(public)/reset-password/+page.svelte
+++ b/code/app/src/routes/(main)/(public)/reset-password/+page.svelte
@@ -1,5 +1,5 @@
<script lang="ts">
- import { create_forgot_password_request } from "$lib/api/user";
+ import { create_forgot_password_request } from "$lib/api/account";
import { Alert, Input, Button } from "$lib/components";
import LL from "$lib/i18n/i18n-svelte";
import type { ErrorResult } from "$lib/models/ErrorResult";
diff --git a/code/app/src/routes/(main)/(public)/reset-password/[id]/+page.svelte b/code/app/src/routes/(main)/(public)/reset-password/[id]/+page.svelte
index c5044b5..3710290 100644
--- a/code/app/src/routes/(main)/(public)/reset-password/[id]/+page.svelte
+++ b/code/app/src/routes/(main)/(public)/reset-password/[id]/+page.svelte
@@ -1,5 +1,5 @@
<script lang="ts">
- import { check_forgot_password_request, fulfill_forgot_password_request } from "$lib/api/user";
+ import { check_forgot_password_request, fulfill_forgot_password_request } from "$lib/api/account";
import { onMount } from "svelte";
import LL from "$lib/i18n/i18n-svelte";
import { Alert, Input, Button } from "$lib/components";
diff --git a/code/app/src/routes/(main)/(public)/sign-in/+page.svelte b/code/app/src/routes/(main)/(public)/sign-in/+page.svelte
index 0e9c07b..d7a8c5a 100644
--- a/code/app/src/routes/(main)/(public)/sign-in/+page.svelte
+++ b/code/app/src/routes/(main)/(public)/sign-in/+page.svelte
@@ -1,10 +1,10 @@
<script lang="ts">
import { goto } from "$app/navigation";
- import { login } from "$lib/api/user";
+ import { login } from "$lib/api/account";
import { Button, Checkbox, Input, Alert } from "$lib/components";
import LL from "$lib/i18n/i18n-svelte";
import type { ErrorResult } from "$lib/models/internal/ErrorResult";
- import type { LoginPayload } from "$lib/models/internal/LoginPayload";
+ import type { LoginPayload } from "$lib/api/account/models/LoginPayload";
import pwKey from "$actions/pwKey";
import { onMount } from "svelte";
import { messageQueryKey, signInPageTestKeys, type Message } from ".";
diff --git a/code/app/src/routes/(main)/(public)/sign-in/index.ts b/code/app/src/routes/(main)/(public)/sign-in/index.ts
index cbdcbf6..c1a1929 100644
--- a/code/app/src/routes/(main)/(public)/sign-in/index.ts
+++ b/code/app/src/routes/(main)/(public)/sign-in/index.ts
@@ -1,18 +1,19 @@
-export enum Message {
+export enum SignInPageMessage {
AFTER_PASSWORD_RESET = "after-password-reset",
USER_INACTIVITY = "user-inactivity",
USER_DISABLED = "user-disabled",
+ LOGGED_OUT = "logged-out"
}
-export const messageQueryKey = "m";
+export const signInPageMessageQueryKey = "m";
export const signInPageTestKeys = {
passwordInput: "password-input",
usernameInput: "username-input",
rememberMeCheckbox: "remember-me-checkbox",
signInForm: "sign-in-form",
- userInactivityAlert: Message.USER_INACTIVITY + "-alert",
- userDisabledAlert: Message.USER_DISABLED + "-alert",
- afterPasswordResetAlert: Message.AFTER_PASSWORD_RESET + "-alert",
+ userInactivityAlert: SignInPageMessage.USER_INACTIVITY + "-alert",
+ userDisabledAlert: SignInPageMessage.USER_DISABLED + "-alert",
+ afterPasswordResetAlert: SignInPageMessage.AFTER_PASSWORD_RESET + "-alert",
formErrorAlert: "form-error-alert",
resetPasswordAnchor: "reset-password-anchor",
signUpAnchor: "sign-up-anchor",
diff --git a/code/app/src/routes/(main)/(public)/sign-up/+page.svelte b/code/app/src/routes/(main)/(public)/sign-up/+page.svelte
index f2f1695..f2b0d7f 100644
--- a/code/app/src/routes/(main)/(public)/sign-up/+page.svelte
+++ b/code/app/src/routes/(main)/(public)/sign-up/+page.svelte
@@ -1,9 +1,9 @@
<script lang="ts">
import { goto } from "$app/navigation";
- import { create_account } from "$lib/api/user";
+ import { create_account } from "$lib/api/account";
import { Button, Input, Alert } from "$lib/components";
import LL from "$lib/i18n/i18n-svelte";
- import type { CreateAccountPayload } from "$lib/models/internal/CreateAccountPayload";
+ import type { CreateAccountPayload } from "$lib/api/account/models/CreateAccountPayload";
import type { ErrorResult } from "$lib/models/internal/ErrorResult";
const formData = {
diff --git a/code/app/src/routes/book/inputs/+page.svelte b/code/app/src/routes/book/inputs/+page.svelte
index e4d19ff..9118a54 100644
--- a/code/app/src/routes/book/inputs/+page.svelte
+++ b/code/app/src/routes/book/inputs/+page.svelte
@@ -1,6 +1,7 @@
<script lang="ts">
import { TextArea, Input, Combobox } from "$lib/components";
import { DatabaseIcon } from "$lib/components/icons";
+ import LL from "$lib/i18n/i18n-svelte";
let value;
let i = 0;
@@ -27,7 +28,13 @@
<section>
<h2>Combobox</h2>
- <Combobox {options} label="Wiii" multiple createable on_create_async={add} />
+ <Combobox
+ {options}
+ label="Wiii"
+ multiple
+ createable
+ on_create_async={add}
+ />
</section>
<section>