mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-28 13:26:16 +03:00
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:
parent
be935ceddf
commit
c90eb122ca
@ -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>
|
||||
|
46
src/lib/components/week/WeekBlockEntry.svelte
Normal file
46
src/lib/components/week/WeekBlockEntry.svelte
Normal 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>
|
1
src/lib/components/week/index.ts
Normal file
1
src/lib/components/week/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as WeekBlockEntry } from "./WeekBlockEntry.svelte";
|
@ -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
33
src/lib/week.ts
Normal 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;
|
||||
};
|
||||
}
|
@ -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>
|
||||
|
@ -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"
|
||||
|
271
src/routes/projects/[projectId]/week/+page.svelte
Normal file
271
src/routes/projects/[projectId]/week/+page.svelte
Normal 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))}
|
||||
—
|
||||
{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>
|
Loading…
Reference in New Issue
Block a user