diff --git a/src/lib/ActiveSession.svelte b/src/lib/ActiveSession.svelte
new file mode 100644
index 0000000..88f97e0
--- /dev/null
+++ b/src/lib/ActiveSession.svelte
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+ {session.name}
+
+
+
+
+
+ Session state |
+ Session start |
+ Hourly rate |
+ Duration |
+
+
+
+
+
+ {sessionStarted ? 'Started' : 'Not started'}
+ |
+
+ {session.startTime && sessionStarted ? startTimeDisplay : 'Not yet started'}
+ |
+ {session.hourlyRate} |
+
+ {duration && sessionStarted && duration > 0 ? formattedDuration : '0h 0m 0s'}
+ |
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/DeleteButton.svelte b/src/lib/DeleteButton.svelte
similarity index 100%
rename from src/components/DeleteButton.svelte
rename to src/lib/DeleteButton.svelte
diff --git a/src/lib/NewSession.svelte b/src/lib/NewSession.svelte
new file mode 100644
index 0000000..bc73736
--- /dev/null
+++ b/src/lib/NewSession.svelte
@@ -0,0 +1,42 @@
+
+
+
diff --git a/src/lib/Sessions.svelte b/src/lib/Sessions.svelte
new file mode 100644
index 0000000..3f693af
--- /dev/null
+++ b/src/lib/Sessions.svelte
@@ -0,0 +1,64 @@
+
+
+
+ {#if sessions.length === 0}
+
No sessions found
+ {:else}
+ {#each sessions as session, i}
+
+
+ {session.name}
+
+
+
+
+
+ Session start |
+ Session end |
+ Hourly rate |
+ Total hours |
+
+
+
+
+
+ {startTimesFormatted[i]}
+ |
+ {endTimesFormatted[i]} |
+ {session.hourlyRate} |
+ {totalHours[i]} |
+
+
+
+
+
+
+ {/each}
+ {/if}
+
diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts
index e1c877d..a7afcbb 100644
--- a/src/routes/+page.server.ts
+++ b/src/routes/+page.server.ts
@@ -1,11 +1,54 @@
import type { PageServerLoad } from './$types';
import type { Session } from '../types/session';
+import type { Actions } from '@sveltejs/kit';
// import { useQuery } from '@sveltestack/svelte-query'
import { fetchData } from '../use/fetch';
export const load = (async () => {
- return { sessions: await fetchData('http://localhost:8000/sessions')}
+ return { sessions: await fetchData('http://localhost:8000/sessions') };
}) satisfies PageServerLoad;
+export const actions: Actions = {
+ sessions: async ({ request }) => {
+ const data = await request.formData();
+ const name = data.get('sessionName');
+ const hourlyRate = data.get('hourlyRate');
+ const session = { name, hourlyRate };
+ const response = await fetch('http://localhost:8000/sessions', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(session)
+ });
+ return {
+ status: response.status
+ };
+ },
+ startSession: async ({ url }) => {
+ const id = url.searchParams.get('id');
+ const res = await fetch(`http://localhost:8000/sessions/${id}`, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });
+ const session: Session = await res.json();
+ session.startTime = new Date().toISOString();
+
+ const response = await fetch(`http://localhost:8000/sessions/${id}`, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(session)
+ });
+
+ return {
+ status: response.status
+ };
+ }
+};
+
// export const load = (() => {
// const queryResult = useQuery('sessions', () => {
// return fetch('http://localhost:8000/sessions').then(res => res.json())
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 3bb618b..9d36bcc 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,61 +1,34 @@
-
- {#if data.sessions.length === 0}
-
No sessions found
- {:else}
- {#each data.sessions as session, i}
-
-
- {session.name}
-
-
-
-
-
- Session start |
- Session end |
- Hourly rate |
- Total hours |
-
-
-
-
-
- {startTimesFormatted[i]}
- |
- {endTimesFormatted[i]} |
- {session.hourlyRate} |
- {totalHours[i]} |
-
-
-
-
-
-
- {/each}
- {/if}
-
+ {#if newSession}
+ {
+ newSession = false;
+ }}
+ />
+ {/if}
+ {#if activeSession}
+
+ {/if}
+
diff --git a/src/types/session.ts b/src/types/session.ts
index 4dc78a3..1c7d01d 100644
--- a/src/types/session.ts
+++ b/src/types/session.ts
@@ -1,8 +1,26 @@
+// export type Session = {
+// _id: string
+// name: string
+// hourlyRate: number
+// } | {
+// _id: string
+// name: string
+// hourlyRate: number
+// startTime: Date
+// } | {
+// _id: string
+// name: string
+// hourlyRate: number
+// startTime: Date
+// endTime: Date
+// hours: number
+// }
+
export interface Session {
- _id: string
- name: string
- hours: number
- startTime: Date
- endTime: Date
- hourlyRate?: number
- }
\ No newline at end of file
+ _id: string;
+ name: string;
+ hourlyRate: number;
+ startTime?: string;
+ endTime?: string;
+ hours?: number;
+}
\ No newline at end of file
diff --git a/src/typings/additional-svelte-typings.d.ts b/src/typings/additional-svelte-typings.d.ts
deleted file mode 100644
index 0b961a0..0000000
--- a/src/typings/additional-svelte-typings.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-declare namespace svelteHTML {
- // enhance attributes
- interface HTMLAttributes {
- 'on:click_outside'?: () => void;
- }
-}
\ No newline at end of file
diff --git a/src/use/time.ts b/src/use/time.ts
index ce13b25..5e3bbe2 100644
--- a/src/use/time.ts
+++ b/src/use/time.ts
@@ -1,4 +1,4 @@
-export const convertISODate = (timestamp: Date): string => {
+export const convertISODate = (timestamp: string): string => {
const date = new Date(timestamp);
const month = (date.getMonth() + 1).toString().padStart(2, '0')
@@ -11,7 +11,7 @@ export const convertISODate = (timestamp: Date): string => {
return `${month}/${day}/${year} ${hours}:${minutes} ${AMorPM}`
}
-export const calculateHours = (startTimestamp: Date, endTimestamp: Date): string => {
+export const calculateHours = (startTimestamp: string, endTimestamp: string): string => {
const start = new Date(startTimestamp);
const end = new Date(endTimestamp);
const diff = end.getTime() - start.getTime();
diff --git a/src/utils/clickOutside.ts b/src/utils/clickOutside.ts
index e15d7e9..d497431 100644
--- a/src/utils/clickOutside.ts
+++ b/src/utils/clickOutside.ts
@@ -1,20 +1,27 @@
-export function clickOutside(node: T) {
- const handleClick = (event: MouseEvent) => {
- if (
- node &&
- event.target instanceof Element &&
- !node.contains(event.target) &&
- !event.defaultPrevented
- ) {
- node.dispatchEvent(new CustomEvent('click_outside', { detail: node }))
- }
- }
+import type { Action } from 'svelte/action';
- document.addEventListener('click', handleClick, true)
+export const clickOutside: Action<
+ HTMLElement,
+ undefined,
+ { 'on:click_outside': (e: CustomEvent<{ detail: HTMLElement }>) => void }
+> = (node) => {
+ const handleClick = (event: MouseEvent) => {
+ console.log(event);
+ if (
+ node &&
+ event.target instanceof Element &&
+ !node.contains(event.target) &&
+ !event.defaultPrevented
+ ) {
+ node.dispatchEvent(new CustomEvent('click_outside', { detail: node }));
+ }
+ };
- return {
- destroy() {
- document.removeEventListener('click', handleClick, true)
- }
- }
-}
\ No newline at end of file
+ document.addEventListener('click', handleClick, true);
+
+ return {
+ destroy() {
+ document.removeEventListener('click', handleClick, true);
+ }
+ };
+};