Skip to content

Commit

Permalink
feat: add new homework page
Browse files Browse the repository at this point in the history
  • Loading branch information
victorDigital committed Aug 20, 2024
1 parent 7a06043 commit 4d441df
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 122 deletions.
96 changes: 49 additions & 47 deletions apps/frontend/src/lib/components/navigation/SidebarLink.svelte
Original file line number Diff line number Diff line change
@@ -1,56 +1,58 @@
<script lang="ts">
import { page } from '$app/stores';
import { sidebarStore } from '$lib/stores';
import BarChart3 from 'lucide-svelte/icons/bar-chart-3';
import CalendarDays from 'lucide-svelte/icons/calendar-days';
import CircleHelp from 'lucide-svelte/icons/circle-help';
import Home from 'lucide-svelte/icons/home';
import ListTodo from 'lucide-svelte/icons/list-todo';
import Mail from 'lucide-svelte/icons/mail';
import BookOpenCheck from 'lucide-svelte/icons/book-open-check';
import { page } from '$app/stores';
import { sidebarStore } from '$lib/stores';
import BarChart3 from 'lucide-svelte/icons/bar-chart-3';
import CalendarDays from 'lucide-svelte/icons/calendar-days';
import CircleHelp from 'lucide-svelte/icons/circle-help';
import Home from 'lucide-svelte/icons/home';
import ListTodo from 'lucide-svelte/icons/list-todo';
import Mail from 'lucide-svelte/icons/mail';
import BookOpenCheck from 'lucide-svelte/icons/book-open-check';
import { NotebookPen } from 'lucide-svelte';
const icons = {
home: Home,
schedule: CalendarDays,
assignments: ListTodo,
messages: Mail,
absence: BarChart3,
grades: BookOpenCheck,
default: CircleHelp
};
const icons = {
home: Home,
schedule: CalendarDays,
assignments: ListTodo,
messages: Mail,
absence: BarChart3,
grades: BookOpenCheck,
homework: NotebookPen,
default: CircleHelp
};
let rawIcon: string = 'default';
export { rawIcon as icon };
export let href: string;
export let label: string;
let rawIcon: string = 'default';
export { rawIcon as icon };
export let href: string;
export let label: string;
// @ts-ignore
$: icon = icons[rawIcon] ?? icons.default;
$: active = href === decodeURI($page.url.pathname);
// @ts-ignore
$: icon = icons[rawIcon] ?? icons.default;
$: active = href === decodeURI($page.url.pathname);
</script>

<a
{href}
class="block unstyled {$sidebarStore.isOpen
? 'w-full rounded-r-3xl'
: 'w-10 ml-4 rounded-3xl'} transition-[border-radius,margin,width] {active
? 'bg-primary text-white dark:text-black'
: 'hover:bg-muted'} cursor-pointer"
on:click
on:keydown
{href}
class="block unstyled {$sidebarStore.isOpen
? 'w-full rounded-r-3xl'
: 'w-10 ml-4 rounded-3xl'} transition-[border-radius,margin,width] {active
? 'bg-primary text-white dark:text-black'
: 'hover:bg-muted'} cursor-pointer"
on:click
on:keydown
>
<div class="flex items-center h-10">
<div class="shrink-0 {$sidebarStore.isOpen ? 'px-6' : 'px-2'} transition-[padding]">
<svelte:component this={icon} class="{active && 'text-white dark:text-black'} size-6" />
</div>
<div class="flex flex-1 overflow-hidden leading-[20px]">
<span
class="{$sidebarStore.isOpen
? 'overflow-visible'
: 'overflow-hidden'} cursor-pointer text-ellipsis text-nowrap"
>
{label}
</span>
</div>
</div>
<div class="flex items-center h-10">
<div class="shrink-0 {$sidebarStore.isOpen ? 'px-6' : 'px-2'} transition-[padding]">
<svelte:component this={icon} class="{active && 'text-white dark:text-black'} size-6" />
</div>
<div class="flex flex-1 overflow-hidden leading-[20px]">
<span
class="{$sidebarStore.isOpen
? 'overflow-visible'
: 'overflow-hidden'} cursor-pointer text-ellipsis text-nowrap"
>
{label}
</span>
</div>
</div>
</a>
53 changes: 27 additions & 26 deletions apps/frontend/src/lib/links.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
export const SITE_LINKS = {
main: {
label: 'Forslag',
links: [
{ href: '/home', label: 'Forside', icon: 'home' },
{ href: '/skema', label: 'Skema', icon: 'schedule' },
{ href: '/opgaver', label: 'Opgaver', icon: 'assignments' },
{ href: '/beskeder', label: 'Beskeder', icon: 'messages' },
{ href: '/fravær', label: 'Fravær', icon: 'absence' },
{ href: '/karakterer', label: 'Karakterer', icon: 'grades' }
]
},
absence: {
label: 'Fravær',
links: [
{ href: '/fravær', label: 'Fraværsoversigt' },
{ href: '/fravær', label: 'Fraværsårsager' }
// { href: '/fravær', label: 'Fraværsregner' }
]
},
other: {
label: 'Andet',
links: [
{ href: '/sync', label: 'Google Synkronisering' },
{ href: '/indstillinger', label: 'Indstillinger' }
]
}
main: {
label: 'Forslag',
links: [
{ href: '/home', label: 'Forside', icon: 'home' },
{ href: '/skema', label: 'Skema', icon: 'schedule' },
{ href: '/opgaver', label: 'Opgaver', icon: 'assignments' },
{ href: '/beskeder', label: 'Beskeder', icon: 'messages' },
{ href: '/fravær', label: 'Fravær', icon: 'absence' },
{ href: '/karakterer', label: 'Karakterer', icon: 'grades' },
{ href: '/lektier', label: 'Lektier', icon: 'homework' }
]
},
absence: {
label: 'Fravær',
links: [
{ href: '/fravær', label: 'Fraværsoversigt' },
{ href: '/fravær', label: 'Fraværsårsager' }
// { href: '/fravær', label: 'Fraværsregner' }
]
},
other: {
label: 'Andet',
links: [
{ href: '/sync', label: 'Google Synkronisering' },
{ href: '/indstillinger', label: 'Indstillinger' }
]
}
};
124 changes: 75 additions & 49 deletions apps/frontend/src/lib/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { stringToColor } from '$lib/utils';
import { NAME_REGEX } from '$lib/utils/other';
import type { GoogleSyncSettings } from '$lib/types/google';
import type { RawLesson } from './types/lesson';
import type { RawHomework } from './types/homework';

export { screenSizeStore } from '$lib/utils'; // To allow importing screenSizeStore from 'stores'

Expand Down Expand Up @@ -56,6 +57,23 @@ export const assignmentStore = lectioDataStore<RawSimpleAssignment[] | null>(
null
);

export const homeworkStore = lectioDataStore<RawHomework[]>('/lektier', 'homework', [], (data) =>
data.map((homework) => ({
...homework,
lesson: {
color: stringToColor(homework.aktivitet.hold ?? '', 100, 90).string,
id: homework.aktivitet.absid,
date: homework.aktivitet.tidspunkt,
class: homework.aktivitet.hold,
name: homework.aktivitet.navn,
note: homework.aktivitet.andet,
room: homework.aktivitet.lokale,
status: homework.aktivitet.status,
teacher: homework.aktivitet.lærer
}
}))
);

export const messageStore = lectioDataStore<Message[] | null, RawMessage[]>(
'/beskeder2',
'messages',
Expand All @@ -70,60 +88,68 @@ export const messageStore = lectioDataStore<Message[] | null, RawMessage[]>(
}))
);

export const frontPageStore = lectioDataStore<FrontPage | null, RawFrontPage>('/forside', 'frontpage', null, (data) => {
let userName = data.overskrift;
const matches = NAME_REGEX.exec(data.overskrift);
if (matches) {
userName = matches[1];
}
export const frontPageStore = lectioDataStore<FrontPage | null, RawFrontPage>(
'/forside',
'frontpage',
null,
(data) => {
let userName = data.overskrift;
const matches = NAME_REGEX.exec(data.overskrift);
if (matches) {
userName = matches[1];
}

return {
lessons: data.skema.map((lesson) => ({
color: stringToColor(lesson.hold ?? '', 100, 90).string,
id: lesson.absid,
date: lesson.tidspunkt,
class: lesson.hold,
name:
lesson.navn
?.replace('prv.', 'prøve')
.replace('mdt.', 'mundtlig')
.replace('skr.', 'skriftlig') ?? null,
note: lesson.andet,
room: lesson.lokale,
status: lesson.status,
teacher: lesson.lærer
})),
assignments:
data.undervisning?.opgaveaflevering?.map((assignment) => ({
id: +assignment.id,
name: assignment.navn,
date: assignment.dato
})) ?? [],
messages: data.kommunikation.beskeder.map((message) => ({
date: message.dato,
id: +message.id,
sender: message.afsender,
title: message.navn
})),
news: data.aktuelt.map((item) => ({
description: item.text.replaceAll('@', '@<!-- -->') // Without this, emails get obfuscated with random hex characters. https://github.com/github/markup/issues/1168
})),
name: userName
};
});
return {
lessons: data.skema.map((lesson) => ({
color: stringToColor(lesson.hold ?? '', 100, 90).string,
id: lesson.absid,
date: lesson.tidspunkt,
class: lesson.hold,
name:
lesson.navn
?.replace('prv.', 'prøve')
.replace('mdt.', 'mundtlig')
.replace('skr.', 'skriftlig') ?? null,
note: lesson.andet,
room: lesson.lokale,
status: lesson.status,
teacher: lesson.lærer
})),
assignments:
data.undervisning?.opgaveaflevering?.map((assignment) => ({
id: +assignment.id,
name: assignment.navn,
date: assignment.dato
})) ?? [],
messages: data.kommunikation.beskeder.map((message) => ({
date: message.dato,
id: +message.id,
sender: message.afsender,
title: message.navn
})),
news: data.aktuelt.map((item) => ({
description: item.text.replaceAll('@', '@<!-- -->') // Without this, emails get obfuscated with random hex characters. https://github.com/github/markup/issues/1168
})),
name: userName
};
}
);

export const absenceStore = lectioDataStore<RawAbsence | null>('/fravaer', 'absence', null);

export const gradesStore = lectioDataStore<RawGrade | null>('/karakterer', 'grades', null);

export const informationStore = lectioDataStore<{
students: { id: string; name: string }[];
groups: string[];
} | null, {
elever: { [key: string]: string };
lærere: { [key: string]: string };
hold_og_grupper: { [key: string]: string };
}>('/informationer', 'information', null, (data) => {
export const informationStore = lectioDataStore<
{
students: { id: string; name: string }[];
groups: string[];
} | null,
{
elever: { [key: string]: string };
lærere: { [key: string]: string };
hold_og_grupper: { [key: string]: string };
}
>('/informationer', 'information', null, (data) => {
const students = Object.entries({ ...data.elever, ...data.lærere }).map(([name, id]) => {
const formatted = name.split(' (')[0].split(' -')[0];
return {
Expand All @@ -138,4 +164,4 @@ export const informationStore = lectioDataStore<{
};
});

export const lessonsStore = localStore<{ [key: number]: RawLesson[] }>('lessons', {});
export const lessonsStore = localStore<{ [key: number]: RawLesson[] }>('lessons', {});
64 changes: 64 additions & 0 deletions apps/frontend/src/routes/lektier/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<script lang="ts">
import { homeworkStore } from '$lib/stores';
import * as Card from '$lib/components/ui/card';
import { onMount } from 'svelte';
import SvelteMarkdown from 'svelte-markdown';
import NewTabLink from '$lib/components/links/NewTabLink.svelte';
import { constructInterval, relativeTime } from '$lib/utils';
import Badge from '$lib/components/ui/badge/badge.svelte';
import Button from '$lib/components/ui/button/button.svelte';
import { ArrowUpRight } from 'lucide-svelte';
let loading = true;
onMount(async () => {
await homeworkStore.fetch();
loading = false;
console.log($homeworkStore);
});
</script>

<div class="page-container">
<h1>Lektier</h1>
{#if loading}
<p>Loading...</p>
{:else if $homeworkStore}
{#each $homeworkStore as homework}
<Card.Root
class={homework.aktivitet.status?.includes('aflyst')
? 'border-destructive dark:border-destructive'
: ''}
>
<Card.Header>
<Card.Title>
<Badge class="mb-2">
<span
use:relativeTime={constructInterval(
homework.aktivitet.tidspunkt
).start?.toJSDate() || new Date()}
/>
</Badge>
<p>{homework.aktivitet.hold}</p>
</Card.Title>
<Card.Description>
{homework.aktivitet.navn}
&sdot; {homework.aktivitet.lokale}
&sdot; {homework.aktivitet.lærer}
</Card.Description>
</Card.Header>
<Card.Content>
<SvelteMarkdown
source={homework.lektier.replaceAll('\n', '<br>')}
renderers={{ link: NewTabLink }}
/>
</Card.Content>
<Card.Footer>
<Button size="sm" href={'/modul?absid=' + homework.aktivitet.absid}>
Gå til modul <ArrowUpRight class="ml-4 size-4" />
</Button>
</Card.Footer>
</Card.Root>
{/each}
{:else}
<p>No homework</p>
{/if}
</div>

0 comments on commit 4d441df

Please sign in to comment.