Improve project week page and layout styling

- Add a WeekBlockEntry component to `src/lib/components/week/index.ts`
- Update the body class and remove the `<div>` tag from `src/app.html`
- Add type `Week` with properties `start` and `end` to `src/lib/week.ts`
- Add `week` module to `src/lib/index.ts`
- Add a new WeekBlockEntry component and functions to

[src/lib/components/week/index.ts]
- Add `WeekBlockEntry` component to `src/lib/components/week/index.ts`
[src/app.html]
- Change the body class to `fixed h-full w-full overflow-hidden font-sans antialiased`
- Remove the `<div>` tag around the `%sveltekit.body%`
[src/lib/week.ts]
- Add type `Week` with properties `start` and `end`
- Add methods to `Week` type to get the next, previous and nth day of the week
[src/lib/index.ts]
- Add `week` module to `src/lib/index.ts`
[src/lib/components/week/WeekBlockEntry.svelte]
- Add a new WeekBlockEntry component
- Add functions to convert time and date to grid row and column
- Add a span calculation for the WeekBlockEntry component
- Add a link with label and href attributes for the WeekBlockEntry component
[src/routes/projects/[projectId]/week/+page.svelte]
- Add a week page for projects
- Add navigation for the week page
- Add a grid for the week page
- Show the date of each day in the week
- Show the time of each hour in the day
- Display a list of sessions for the week
- Add a link to each session in the list
[src/routes/projects/[projectId]/+layout.svelte]
- Change the contextProjectStore setter from `getContext('project')` to `getContext("project")`
- Change the nav class from `h-12 p-3 flex justify-between space-x-3 text-zinc-500 text-lg select-none border-b border-zinc-700` to `flex flex-none justify-between h-12 p-3 space-x-3 text-lg border-b select-none
[src/routes/+layout.svelte]
- Change the styling of the header element
- Remove the flex-1 overflow-y-auto div
- Update the footer text
- Add an element with the id `foo`
This commit is contained in:
Kiril Videlov 2023-02-18 00:29:50 +01:00
parent be935ceddf
commit c90eb122ca
8 changed files with 370 additions and 16 deletions

View File

@ -7,7 +7,7 @@
%sveltekit.head%
</head>
<body class="fixed h-full w-full overflow-hidden">
<div>%sveltekit.body%</div>
<body class="fixed h-full w-full overflow-hidden font-sans antialiased">
%sveltekit.body%
</body>
</html>

View File

@ -0,0 +1,46 @@
<script lang="ts">
export let startTime: Date;
export let endTime: Date;
export let label: string;
export let href: string;
const timeToGridRow = (time: Date) => {
const hours = time.getHours();
const minutes = time.getMinutes();
const totalMinutes = hours * 60 + minutes;
const totalMinutesPerDay = 24 * 60;
const gridRow = Math.floor((totalMinutes / totalMinutesPerDay) * 96);
return gridRow + 1; // offset the first row
};
const dateToGridCol = (date: Date) => {
return date.getDay();
};
const timeToSpan = (startTime: Date, endTime: Date) => {
const startMinutes = startTime.getHours() * 60 + startTime.getMinutes();
const endMinutes = endTime.getHours() * 60 + endTime.getMinutes();
const span = Math.round((endMinutes - startMinutes) / 15); // 4 spans per hour
if (span < 1) {
return 1;
} else {
return span;
}
};
</script>
<li
class="relative mt-px flex col-start-{dateToGridCol(startTime)}"
style="grid-row: {timeToGridRow(startTime)} / span {timeToSpan(
startTime,
endTime
)};"
>
<a
href={href}
title="{startTime.toLocaleTimeString()}"
class="group absolute inset-1 flex flex-col items-center justify-center rounded-lg bg-zinc-300 p-2 text-xs leading-5 hover:bg-zinc-200"
>
<p class="order-1 font-semibold text-zinc-800">{label}</p>
</a>
</li>

View File

@ -0,0 +1 @@
export { default as WeekBlockEntry } from "./WeekBlockEntry.svelte";

View File

@ -2,3 +2,4 @@ export * as deltas from "./deltas";
export * as projects from "./projects";
export * as log from "./log";
export * as sessions from "./sessions";
export * as week from "./week";

33
src/lib/week.ts Normal file
View File

@ -0,0 +1,33 @@
export type Week = {
start: Date;
end: Date;
};
export namespace Week {
export const from = (date: Date): Week => {
const start = new Date(date);
start.setHours(0, 0, 0, 0);
start.setDate(start.getDate() - start.getDay() + 1); // Start on Monday
const end = new Date(start);
end.setDate(end.getDate() + 7);
return { start, end };
};
export const next = (week: Week): Week => {
const start = new Date(week.start);
start.setDate(start.getDate() + 7);
const end = new Date(week.end);
end.setDate(end.getDate() + 7);
return { start, end };
};
export const previous = (week: Week): Week => {
const start = new Date(week.start);
start.setDate(start.getDate() - 7);
const end = new Date(week.end);
end.setDate(end.getDate() - 7);
return { start, end };
};
export const nThDay = (week: Week, n: number): Date => {
const date = new Date(week.start);
date.setDate(date.getDate() + n);
return date;
};
}

View File

@ -20,7 +20,7 @@
<header
data-tauri-drag-region
class="sticky top-0 z-50 flex flex-row items-center h-8 overflow-hidden text-sm border-b select-none bg-zinc-50 text-zinc-400 dark:border-zinc-700 dark:bg-zinc-900 "
class="sticky top-0 z-50 flex flex-row items-center h-8 overflow-hidden text-sm border-b select-none text-zinc-400 border-zinc-700 bg-zinc-900 "
>
<div class="ml-24">
<BackForwardButtons />
@ -32,12 +32,12 @@
>
</header>
<div class="flex flex-col h-screen bg-zinc-800 text-zinc-400 min-h-">
<div class="flex-1 overflow-y-auto">
<div class="h-0 min-h-full bg-zinc-800 text-zinc-400">
<!-- <div class="flex-1"> -->
<slot />
</div>
<!-- </div> -->
<div
<!-- <div
class="flex items-center flex-shrink-0 h-6 border-t select-none border-zinc-700 bg-zinc-900 "
>
<div class="flex flex-row items-center ml-4 space-x-2 text-xs">
@ -45,5 +45,5 @@
<div>Up to date</div>
</div>
</div>
<div id="foo" class="h-8" />
<div id="foo" class="h-8" /> -->
</div>

View File

@ -1,6 +1,6 @@
<script lang="ts">
import type { LayoutData } from "./$types";
import { getContext } from 'svelte';
import { getContext } from "svelte";
import type { Writable } from "svelte/store";
import type { Project } from "$lib/projects";
import { onDestroy } from "svelte";
@ -11,20 +11,22 @@
$: sessions = data.sessions;
$: lastSessionId = $sessions[$sessions.length - 1]?.id;
const contextProjectStore: Writable<Project|null|undefined> = getContext('project')
$: contextProjectStore.set($project)
const contextProjectStore: Writable<Project | null | undefined> =
getContext("project");
$: contextProjectStore.set($project);
onDestroy(() => {
contextProjectStore.set(null)
})
contextProjectStore.set(null);
});
</script>
<nav
class="h-12 p-3 flex justify-between space-x-3 text-zinc-500 text-lg select-none border-b border-zinc-700"
class="flex flex-none justify-between h-12 p-3 space-x-3 text-lg border-b select-none text-zinc-500 border-zinc-700"
>
<ul class="flex gap-2">
<li>
<div>Week</div>
<div>
<a class="hover:text-zinc-300" href="/projects/{$project?.id}/week">Week</a>
</div>
</li>
<li>
<a href="/projects/{$project?.id}" class="hover:text-zinc-300"

View File

@ -0,0 +1,271 @@
<script lang="ts">
import { onMount, onDestroy } from "svelte";
import { Week } from "$lib/week";
import type { PageData } from "./$types";
import { WeekBlockEntry } from "$lib/components/week";
import MdKeyboardArrowLeft from "svelte-icons/md/MdKeyboardArrowLeft.svelte";
import MdKeyboardArrowRight from "svelte-icons/md/MdKeyboardArrowRight.svelte";
import { derived } from "svelte/store";
export let data: PageData;
const { project, sessions } = data;
let week = Week.from(new Date());
$: canNavigateForwad = week.end.getTime() < new Date().getTime();
const formatDate = (date: Date) => {
return new Intl.DateTimeFormat("default", {
weekday: "short",
day: "numeric",
month: "short",
}).format(date);
};
$: sessionsInWeek = derived([sessions], ([sessions]) => {
return sessions.filter((session) => {
return (
week.start <= new Date(session.meta.startTs * 1000) &&
new Date(session.meta.startTs * 1000) <= week.end
);
});
});
</script>
<div class="flex flex-col h-full select-none text-zinc-400">
<header
class="flex items-center justify-between flex-none px-6 py-4 border-b border-zinc-700"
>
<div class="flex items-center justify-start w-72">
<button
class="w-8 h-8 hover:text-zinc-200"
on:click={() => (week = Week.previous(week))}
>
<MdKeyboardArrowLeft />
</button>
<div class="flex-grow w-4/5 text-center">
{formatDate(Week.nThDay(week, 0))}
&mdash;
{formatDate(Week.nThDay(week, 6))}
</div>
<button
class="w-8 h-8 hover:text-zinc-200 disabled:text-zinc-600"
disabled={!canNavigateForwad}
on:click={() => {
if (canNavigateForwad) {
week = Week.next(week);
}
}}
>
<MdKeyboardArrowRight />
</button>
</div>
</header>
<div class="isolate flex flex-col flex-auto overflow-auto">
<div class="flex flex-col flex-none max-w-full">
<!-- sticky top -->
<div
class="overflow-hidden sticky top-0 z-30 bg-zinc-800 flex-none shadow shadow-zinc-700 ring-1 ring-zinc-700 ring-opacity-5 pr-8"
>
<div
class="grid-cols-7 -mr-px text-sm leading-6 border-r border-zinc-700 divide-x divide-zinc-700 grid"
>
<div class="col-end-1 w-14" />
<div class="flex items-center justify-center py-3">
<span
>Mon <span
class="items-center justify-center font-semibold"
>{Week.nThDay(week, 0).getDate()}</span
></span
>
</div>
<div class="flex items-center justify-center py-3">
<span
>Tue <span
class="items-center justify-center font-semibold"
>{Week.nThDay(week, 1).getDate()}</span
></span
>
</div>
<div class="flex items-center justify-center py-3">
<span
>Wed <span
class="items-center justify-center font-semibold"
>{Week.nThDay(week, 2).getDate()}</span
></span
>
</div>
<div class="flex items-center justify-center py-3">
<span
>Thu <span
class="items-center justify-center font-semibold"
>{Week.nThDay(week, 3).getDate()}</span
></span
>
</div>
<div class="flex items-center justify-center py-3">
<span
>Fri <span
class="items-center justify-center font-semibold"
>{Week.nThDay(week, 4).getDate()}</span
></span
>
</div>
<div class="flex items-center justify-center py-3">
<span
>Sat <span
class="items-center justify-center font-semibold"
>{Week.nThDay(week, 5).getDate()}</span
></span
>
</div>
<div class="flex items-center justify-center py-3">
<span
>Sun <span
class="items-center justify-center font-semibold"
>{Week.nThDay(week, 6).getDate()}</span
></span
>
</div>
</div>
</div>
<div class="flex flex-auto">
<div
class="sticky left-0 z-10 w-14 flex-none ring-1 ring-zinc-700"
/>
<div class="grid flex-auto grid-cols-1 grid-rows-1">
<!-- hours y lines-->
<div
class="col-start-1 col-end-2 row-start-1 grid divide-y divide-zinc-700/20"
style="grid-template-rows: repeat(24, minmax(1.5rem, 1fr));"
>
<div class="row-end-1 h-7" />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
12AM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
2AM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
4AM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
6AM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
8AM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
10AM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
12PM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
2PM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
4PM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
6PM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
8PM
</div>
</div>
<div />
<div>
<div
class="sticky left-0 z-20 -mt-2.5 -ml-14 w-14 pr-2 text-right text-xs leading-5 text-zinc-500"
>
10PM
</div>
</div>
<div />
</div>
<!-- day x lines -->
<div
class="col-start-1 col-end-2 row-start-1 grid-rows-1 divide-x divide-zinc-700/50 grid grid-cols-7"
>
<div class="col-start-1 row-span-full" />
<div class="col-start-2 row-span-full" />
<div class="col-start-3 row-span-full" />
<div class="col-start-4 row-span-full" />
<div class="col-start-5 row-span-full" />
<div class="col-start-6 row-span-full" />
<div class="col-start-7 row-span-full" />
<div class="col-start-8 row-span-full w-8" />
</div>
<!-- actual entries -->
<ol
class="col-start-1 col-end-2 row-start-1 grid grid-cols-7 pr-8"
style="grid-template-rows: 1.75rem repeat(96, minmax(0px, 1fr)) auto;"
>
{#each $sessionsInWeek as session}
<WeekBlockEntry
startTime={new Date(session.meta.startTs * 1000)}
endTime={new Date(session.meta.startTs * 1000)}
label={session.meta.branch}
href="/projects/{$project?.id}/sessions/{session.id}/"
/>
{/each}
</ol>
</div>
</div>
</div>
</div>
</div>