Skip to content
This repository has been archived by the owner on Jun 25, 2024. It is now read-only.

Timetables #15

Merged
merged 10 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
},
"type": "module",
"dependencies": {
"@svelte-plugins/datepicker": "^1.0.2",
"@tailwindcss/container-queries": "^0.1.1",
"html2canvas": "^1.4.1",
"svelte-markdown": "^0.4.1"
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions src/constants/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ const rawLauncherLinks: {
description: 'nav.settings.colors.description',
query: ['colors', 'farben', 'fach', 'fächer', 'subject', 'bunt', 'colorfull']
},
{
title: 'nav.settings.timetable',
action: () => goto('/settings/timetable'),
bxIcon: 'bx-calendar',
description: 'nav.settings.timetable.description',
query: [
'timetable',
'stundenplan',
'fächer',
'fach',
'subjects',
'subject',
'autocomplete',
'autovervollständigung'
]
},
{
title: 'nav.settings.preferences',
action: () => goto('/settings/preferences'),
Expand Down
16 changes: 16 additions & 0 deletions src/constants/weekDays.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const weekdays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'] as const;
export const emptyTimeTable = {
mo: [],
tu: [],
we: [],
th: [],
fr: [],
sa: [],
su: []
} as TimeTable;

export type WeekDay = (typeof weekdays)[number];

export type TimeTable = {
[day in WeekDay]: string[];
};
12 changes: 12 additions & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ const de = {
'Hier kannst du ein paar Tricks sehen. Sie sind aufjedenfall einen Blick Wert ;)',
'nav.settings.colors': 'Farben für Fächer',
'nav.settings.colors.description': 'Hier kannst du die Farben für deine Fächer ändern.',
'nav.settings.timetable': 'Stundenplan',
'nav.settings.timetable.description': 'Hier kannst du deinen Stundenplan ändern.',
'nav.settings.preferences': 'Präferenzen',
'nav.settings.preferences.description':
'Hier kannst du deine Präferenzen ändern. Wie z.B. das Erscheinungsbild.',
Expand Down Expand Up @@ -163,6 +165,13 @@ const de = {
'settings.preferences': 'Einstellungen',
'settings.colors': 'Farben',
'settings.api': 'API Einstellungen',
'settings.timetable': 'Stundenplan',
'settings.timetable.reset': 'Zurücksetzen',
'settings.timetable.useForAutoComplete': 'Nutze den Stundenplan für die Autovervollständigung',
'settings.timetable.export': 'Exportieren',
'settings.timetable.import': 'Importieren',
'settings.timetable.import.confirm':
'Bist du sicher, dass du den Stundenplan importieren möchtest? Der aktuelle Stundenplan wird überschrieben!',
'settings.selectSpecificSection':
'Wähle links eine spezifische Sektion aus, um die Einstellungen zu ändern.',
'settings.apperance': 'Aussehen',
Expand Down Expand Up @@ -304,6 +313,9 @@ const de = {
'toast.download.homework.success': 'Hausaufgaben erfolgreich heruntergeladen.',
'toast.download.homework.error': 'Hausaufgaben konnten nicht heruntergeladen werden.',

'toast.file.InvalidFile': 'Die Datei ist ungültig :(',
'toast.file.ReadError': 'Die Datei konnte nicht gelesen werden :(',

'toast.colors.import.success': 'Farben erfolgreich importiert.',
'toast.colors.import.invalidFile': 'Die Datei ist ungültig :(',
'toast.colors.import.error': 'Farben konnten nicht importiert werden.',
Expand Down
12 changes: 12 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ const en = {
'nav.tricks.description': 'Here you can see some tricks, defeniately worth a look!',
'nav.settings.colors': 'Colors for subjects',
'nav.settings.colors.description': 'Here you can change the colors for your subjects',
'nav.settings.timetable': 'Timetable',
'nav.settings.timetable.description': 'Here you can edit your timetable',
'nav.settings.preferences': 'Preferences',
'nav.settings.preferences.description': 'Here you can change your preferences like the theme.',
'nav.search': 'Search',
Expand Down Expand Up @@ -159,6 +161,13 @@ const en = {
'settings.preferences': 'Preferences',
'settings.colors': 'Colors',
'settings.api': 'API-Settings',
'settings.timetable': 'Timetable',
'settings.timetable.reset': 'Reset',
'settings.timetable.useForAutoComplete': 'Use this timetable for auto complete',
'settings.timetable.export': 'Export',
'settings.timetable.import': 'Import',
'settings.timetable.import.confirm':
'Are you sure you want to import this timetable? This will overwrite your current timetable!',
'settings.selectSpecificSection': 'Select a specific section on the left to change its settings',
'settings.apperance': 'Apperance',
'settings.apperance.theme': 'Theme',
Expand Down Expand Up @@ -296,6 +305,9 @@ const en = {
'toast.download.homework.success': 'Successfully downloaded homework',
'toast.download.homework.error': 'Failed to download homework',

'toast.file.InvalidFile': 'Invalid file :(',
'toast.file.ReadError': 'This file could not be read :(',

'toast.colors.import.success': 'Farben erfolgreich importiert.',
'toast.colors.import.invalidFile': 'Die Datei ist ungültig :(',
'toast.colors.import.error': 'Farben konnten nicht importiert werden.',
Expand Down
11 changes: 9 additions & 2 deletions src/lib/dates/DatePicker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { getDateInInputFormat } from '$lib/dates/getDateInInputFormat';
import DateLabel from './dateLabel.svelte';
import type { CustomDate } from '../../types/customDate';
import { onMount } from 'svelte';
import { createEventDispatcher, onMount } from 'svelte';
import I18n from '$lib/I18n.svelte';
import { i } from '../../languages/i18n';

Expand All @@ -15,11 +15,15 @@
let dateInput: HTMLInputElement;
let isSafari = false;

const dispatcher = createEventDispatcher();

onMount(() => {
isSafari = navigator.userAgent.toLocaleLowerCase().includes('safari');
});

$: dateObj = createDate(new Date(date));
$: {
dateObj = createDate(new Date(date));
}
</script>

<div class="row">
Expand All @@ -28,6 +32,9 @@
bind:value={date}
id={isSafari ? 'safari-date-picker' : 'heading-input'}
bind:this={dateInput}
on:input={() => {
dispatcher('input', dateObj);
}}
/>
{#if !isSafari}
<DateLabel date={dateObj} />
Expand Down
10 changes: 5 additions & 5 deletions src/lib/dates/createDateObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import type { CustomDate, CustomDateTime } from '../../types/customDate';

export function createDate(d: Date): CustomDate {
return {
day: d.getUTCDate(),
month: d.getUTCMonth() + 1,
year: d.getUTCFullYear()
day: d.getDate(),
month: d.getMonth() + 1,
year: d.getFullYear()
};
}

export function createDateTime(d: Date): CustomDateTime {
return {
...createDate(d),
hour: d.getUTCHours(),
minute: d.getUTCMinutes()
hour: d.getHours(),
minute: d.getMinutes()
};
}

Expand Down
49 changes: 49 additions & 0 deletions src/lib/dates/dataWeekday.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { WeekDay } from '../../constants/weekDays';
import { i, type T, type Token } from '../../languages/i18n';
import type { CustomDate } from '../../types/customDate';

const token = [
'date.sunday',
Expand All @@ -25,4 +27,51 @@ export function getWeekdayByDate(date: { day: number; month: number; year: numbe
return weekdays[dateObj.getDay()] as WeekdayTranslation;
}

/**
* A function to give a weekday by abbreviation.
* @param abbreviation The abbreviation of the weekday
* @returns A translation of the weekday
*/
export function getWeekdayByAbbreviation(abbreviation: WeekDay) {
const longWeekdayToken = (
{
mo: 'date.monday',
tu: 'date.tuesday',
we: 'date.wednesday',
th: 'date.thursday',
fr: 'date.friday',
sa: 'date.saturday',
su: 'date.sunday'
} satisfies Record<WeekDay, Token>
)[abbreviation];

return i(longWeekdayToken, {}, {
transform: 'capitalize'
} as const);
}

export const getWeekdayAbbreviationByDate = (date: CustomDate) => {
const dateObj = new Date(date.year, date.month - 1, date.day);
const weekdayIndex = dateObj.getDay();

switch (weekdayIndex) {
case 0:
return 'su';
case 1:
return 'mo';
case 2:
return 'tu';
case 3:
return 'we';
case 4:
return 'th';
case 5:
return 'fr';
case 6:
return 'sa';
default:
return 'mo';
}
};

export const getWeekdays = () => token.map((key) => i(key)) as WeekdayTranslation[];
49 changes: 49 additions & 0 deletions src/lib/files/readFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export const selectFile = async (accept: string) => {
const input = document.createElement('input');
input.type = 'file';
input.accept = accept;

return new Promise<File | undefined>((resolve, reject) => {
input.onchange = async () => {
const files = input.files;
if (!files) {
reject('No file selected');
return;
}
const file = files[0];
if (!file) {
reject('No file selected');
return;
}

resolve(file);
};
input.click();
});
};

export const readFileContent = (file: File): Promise<string> => {
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onload = (event) => {
const result = event.target?.result;
if (typeof result !== 'string') {
reject('Could not read file');
return;
}
resolve(result);
};
reader.onerror = (error) => reject(error);
reader.readAsText(file);
});
};

export const getFile = async (accept: string) => {
const file = await selectFile(accept).catch(() => undefined);
if (!file) {
return;
}
const content = await readFileContent(file);

return { file, content };
};
15 changes: 15 additions & 0 deletions src/lib/helpers/mapValues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
type ObjectOf<T> = Record<string | number | symbol, T>;

/**
* Map over the values of an object, returning a new object with the same keys
* and mapped values.
*/
export const mapValues = <T, U>(object: ObjectOf<T>, fn: (value: T) => U) => {
// iterate over the keys of the object
const newObject: ObjectOf<U> = {};
for (const key of Object.keys(object)) {
const mappedValue = fn(object[key]);
newObject[key] = mappedValue;
}
return newObject;
};
5 changes: 2 additions & 3 deletions src/lib/homework/CreateHomework.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import SubmitButton from '$lib/SubmitButton.svelte';
import { createDate } from '$lib/dates/createDateObject';
import Box from './Box.svelte';
import type { CustomDate } from '../../types/customDate';
import type { Assignment } from '../../types/homework';
import CreateHomeworkInner from './CreateHomeworkInner.svelte';
import I18n from '$lib/I18n.svelte';
Expand All @@ -19,7 +18,7 @@
return;
};

let assignedAtDateObj: CustomDate;
let assignedAtDateObj = createDate(new Date());

let assignments: Assignment[] = [
{
Expand Down Expand Up @@ -96,7 +95,7 @@
<h3 class="mb-4">
<DatePicker bind:dateObj={assignedAtDateObj} />
</h3>
<CreateHomeworkInner bind:assignments />
<CreateHomeworkInner bind:assignments bind:date={assignedAtDateObj} />
<I18n>
<SubmitButton value={i('homework.add.submit')} disabled={submitButtonDisabled} />
</I18n>
Expand Down
Loading
Loading