Skip to content

Commit

Permalink
feat: better error handling on creation
Browse files Browse the repository at this point in the history
  • Loading branch information
shivan-s committed Jun 15, 2023
1 parent 7a991be commit bec53e6
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 74 deletions.
4 changes: 3 additions & 1 deletion client/src/app.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
declare global {
namespace App {
// interface Error {}
// interface Locals {}
interface Locals {
LIMIT: number;
}
// interface PageData {}
interface Platform {
env?: {
Expand Down
5 changes: 2 additions & 3 deletions client/src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { Handle } from '@sveltejs/kit';
import connection from '$lib/db';

export const handle = (async ({ event, resolve }) => {
const { platform, locals } = event;
locals.db = connection(platform?.env?.DB);
const { locals } = event;
locals.LIMIT = 2;
const response = await resolve(event);
return response;
}) satisfies Handle;
33 changes: 12 additions & 21 deletions client/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<script>
import { fade } from 'svelte/transition';
</script>

<svelte:head><title>Shivan's Learning</title></svelte:head>

<header>
<h1><a href="/">Learning</a></h1>
<a href="/auth/create">Create</a>
<a data-sveltekit-reload href="/auth/create">Create</a>
</header>
<main>
<main transition:fade>
<slot />
</main>
<footer />
Expand Down Expand Up @@ -65,19 +69,9 @@
:global(textarea) {
width: 100%;
resize: none;
}
:global(textarea:focus) {
height: 8rem;
}
:global(textarea .error) {
border: 2px solid var(--danger-color);
}
:global(textarea:focus .error) {
border: 2px solid var(--danger-color);
}
:global(button) {
cursor: pointer;
}
Expand Down Expand Up @@ -152,6 +146,12 @@
animation-name: animate-fade;
animation-fill-mode: backwards;
}
:global(.error) {
border: 2px solid var(--danger-color);
}
:global(.error-message) {
color: var(--danger-text);
}
main {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -197,15 +197,6 @@
display: flex;
align-items: center;
gap: 1rem;
border-style: solid;
border-bottom: 1px;
border-color: var(--secondary-color);
}
header a {
border-style: solid;
border-color: primary;
border-left: 1px;
border-color: var(--secondary-color);
}
@keyframes -global-animate-fade {
Expand Down
50 changes: 16 additions & 34 deletions client/src/routes/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,23 @@ export const actions = {
}
} satisfies Actions;

export const load = (async ({ platform, url }) => {
export const load = (async ({ platform, url, locals }) => {
const { LIMIT } = locals;
const q = url.searchParams.get('q');
const topicFilter = url.searchParams.get('topic');
const cursor = url.searchParams.get('cursor');
const db = connection(platform?.env?.DB);
const { count } = db.fn;
const topics = await db
.selectFrom('topics')
.where('deleted_at', 'is', null)
.select(['name', 'id'])
.execute();
const learningsTotal = await db
.selectFrom('learnings')
.where('learnings.deleted_at', 'is', null)
.select(count('id').as('count'))
.executeTakeFirst();
const learnings = await db
.selectFrom('learnings')
.where('learnings.deleted_at', 'is', null)
Expand All @@ -42,7 +50,8 @@ export const load = (async ({ platform, url }) => {
'learnings.created_at as createdAt',
'learnings.updated_at as updatedAt',
'learnings.content as content',
'topics.name as topic'
'topics.name as topic',
count('learnings.id').as('numLearnings')
])
.$if(q !== null && q.length > 0, (qb) =>
qb.where(({ or, cmpr }) => or([cmpr('content', 'like', q), cmpr('topics.name', 'like', q)]))
Expand All @@ -51,7 +60,10 @@ export const load = (async ({ platform, url }) => {
qb.where('topics.id', '=', parseInt(topicFilter ?? ''))
)
.orderBy('createdAt', 'desc')
.limit(LIMIT)
.$if(cursor !== null, (qb) => qb.offset((parseInt(cursor || '0') || 0) * LIMIT))
.execute();
const nextCursor = parseInt(cursor || '0') || 0 + 1;
const randomLearning = await db
.selectFrom('learnings')
.where('learnings.deleted_at', 'is', null)
Expand All @@ -66,42 +78,12 @@ export const load = (async ({ platform, url }) => {
.limit(1)
.executeTakeFirst();
return {
learningsTotal,
nextCursor,
topics,
learnings,
randomLearning,
q,
topicId: topicFilter
};
}) satisfies PageServerLoad;

/* const learnings: Learning[] = [ */
/* { */
/* date: '2023-05-28', */
/* topic: 'Flying', */
/* learning: */
/* 'Learning about climbing and descending. Remember the pull the carb out when below 1300 RPMs!' */
/* }, */
/* { */
/* date: '2023-05-28', */
/* topic: 'Golf', */
/* learning: */
/* 'Making good contact. Focus on reducing the wrist action. Practice but make sure you hit the ground.' */
/* }, */
/* { */
/* date: '2023-05-28', */
/* topic: 'Brazilian Jiu Jitsu', */
/* learning: */
/* "Fun roll. Maintain a good base. Do not stay on back. Try and antipate opponent's move and don't stop moving." */
/* }, */
/* { */
/* date: '2023-05-29', */
/* topic: 'Brazilian Jiu Jitsu', */
/* learning: 'Learnt about deep half guard from mount and half guard.' */
/* }, */
/* { */
/* date: '2023-05-29', */
/* topic: 'Programming', */
/* learning: */
/* 'The Alignment Problem: Reinforcement learning - incentivise for A but end up getting B. Deep Learning with Python: Gradient descent, backpropagation, overview. Rust: tui-rs' */
/* } */
/* ]; */
14 changes: 10 additions & 4 deletions client/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import type { PageData, ActionData } from './$types';
import { loading } from '$lib/stores';
import { enhance } from '$app/forms';
export let data: PageData;
export let form: ActionData;
$: ({ learnings, topics, topicId, q, randomLearning } = data);
$: ({ learnings, topics, topicId, q, randomLearning, nextCursor, learningsTotal } = data);
if (form?.randomLearning) {
randomLearning = form.randomLearning;
}
console.log(data);
console.log(form);
</script>

{#if randomLearning}
<div in:fade out:fade style="min-height: 10rem">
<div style="min-height: 10rem">
<p>{new Date(randomLearning.createdAt).toLocaleDateString()}</p>
<p><strong>{randomLearning.topic}</strong></p>
<p>{randomLearning.content}</p>
Expand Down Expand Up @@ -44,12 +46,16 @@
<button type="submit" disabled={$loading}>Search</button>
</form>
{#each learnings as { createdAt, topic, content }}
<div in:fade>
<div>
<p>{new Date(createdAt).toLocaleDateString()}</p>
<p><strong>{topic}</strong></p>
<p>{content}</p>
</div>
{/each}
<form method="GET">
<input name="cursor" type="hidden" value={nextCursor} />
<button type="submit">Load more</button>
</form>
{:else}
<p style="text-align: center">
No learnings. Please <a href="/auth/create/">create</a> some learnings to share.
Expand Down
3 changes: 2 additions & 1 deletion client/src/routes/auth/create/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ export const actions = {
content
});
if (!result.success) {
const error = result.error.flatten().fieldErrors;
return {
success: false,
error: JSON.stringify(result.error),
error,
topicId,
content
};
Expand Down
15 changes: 5 additions & 10 deletions client/src/routes/auth/create/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script lang="ts">
import { enhance } from '$app/forms';
import type { ActionData, PageData } from './$types';
import { fade } from 'svelte/transition';
import { loading } from '$lib/stores';
export let data: PageData;
Expand Down Expand Up @@ -34,23 +33,20 @@
</select>
</label>
<label style="position: relative">
<textarea name="content" bind:value={content} class={form?.error && 'error'} />
<textarea class={form?.error?.content && 'error'} name="content" bind:value={content} />
<p style="position: absolute; bottom: 0px; right: 0px; padding: 0.5rem 0.25rem;">
({content.length}/{totalChar})
</p>
</label>
<button type="submit" disabled={$loading}>Create</button>
{#if form?.error?.content}
<span class="error-message">{form.error.content.join('. ')}</span>
{/if}
</form>
<hr style="border-top: 1px solid gray" />
{#if form?.error}
<p class="error-message">{form.error}</p>
{/if}
<div>
{#each learnings as { learningId, createdAt, updatedAt, deletedAt, topic, topicId, content }}
<div
in:fade
class={form?.requestEditLearning?.learningId === learningId ? 'visible' : 'hidden'}
>
<div class={form?.requestEditLearning?.learningId === learningId ? 'visible' : 'hidden'}>
<p>
{new Date(createdAt).toLocaleDateString()}
{createdAt != updatedAt && `Updated ${new Date(updatedAt).toLocaleDateString()}`}
Expand Down Expand Up @@ -89,7 +85,6 @@
</div>
</div>
<div
in:fade
class="{form?.requestEditLearning?.learningId === learningId
? 'hidden'
: 'visible'} learning {deletedAt && 'deleted'}
Expand Down

0 comments on commit bec53e6

Please sign in to comment.