feat: improve UI/UX

This commit is contained in:
Pihkaal
2025-11-05 17:36:31 +01:00
parent d2c8591ddb
commit eb08d76bf2
3 changed files with 98 additions and 42 deletions

View File

@@ -2,9 +2,10 @@
"manifest_version": 3,
"name": "gestime.aphp.fr exporter",
"version": "1.0.0",
"description": "TBD",
"description": "Export your Gestime work schedule to an ICS calendar file",
"action": {
"default_popup": "index.html"
"default_popup": "index.html",
"default_popup_width": 450
},
"permissions": ["activeTab", "scripting"],
"host_permissions": ["http://gestime.aphp.fr/*"]

View File

@@ -1,39 +1,95 @@
<script setup lang="ts">
import { ref } from "vue";
import { extractData } from "@/utils/data";
import { generateIcsCalendar } from "ts-ics";
const downloadCalendar = async () => {
const calendar = await extractData();
if (!calendar) {
// TODO: report error
return;
}
const error = ref<string | null>(null);
const downloadCalendar = async () => {
error.value = null;
await new Promise((resolve) =>
setTimeout(resolve, 1000 + Math.random() * 500),
);
let downloadUrl: string | null = null;
try {
// extract data and convert to ics
const calendar = await extractData();
const icsContent = generateIcsCalendar(calendar.data);
const blob = new Blob([icsContent], { type: "text/calendar;charset=utf-8" });
const url = URL.createObjectURL(blob);
try {
// create blob from ics content then download
const blob = new Blob([icsContent], {
type: "text/calendar;charset=utf-8",
});
downloadUrl = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.href = downloadUrl;
link.download = calendar.name;
link.click();
} catch (err: unknown) {
error.value = err instanceof Error ? err.message : String(err);
} finally {
URL.revokeObjectURL(url);
if (downloadUrl) URL.revokeObjectURL(downloadUrl);
}
};
</script>
<template>
<UApp>
<div class="app">
<h1>Gestime APHP Export</h1>
<UCard class="w-[450px] rounded-none">
<template #header>
<div class="flex items-center justify-between">
<h1 class="text-xl font-bold text-gray-900 dark:text-white">
Gestime APHP Export
</h1>
<div class="flex items-center gap-2">
<UButton
icon="i-lucide-github"
to="https://github.com/pihkaal/gestime-aphp-export"
target="_blank"
color="neutral"
variant="ghost"
size="md"
/>
<UColorModeButton size="md" />
</div>
</div>
</template>
<div class="space-y-4">
<div class="space-y-2">
<UButton
loading-auto
label="Download calendar"
label="Download Calendar"
icon="i-lucide-download"
size="lg"
block
color="secondary"
variant="subtle"
@click="downloadCalendar"
/>
<UAlert
v-if="error"
color="error"
icon="i-lucide-circle-x"
:title="error"
/>
</div>
<UButton
label="Import in Google Calendar"
icon="i-lucide-external-link"
size="lg"
block
color="secondary"
variant="subtle"
to="https://calendar.google.com/calendar/u/0/r/settings/export"
target="_blank"
/>
</div>
</UCard>
</UApp>
</template>

View File

@@ -50,25 +50,23 @@ const makeIcsCalendar = (events: IcsEvent[]): IcsCalendar => ({
export async function extractData(): Promise<{
name: string;
data: IcsCalendar;
} | null> {
try {
}> {
const [tab] = await chrome.tabs.query({
active: true,
currentWindow: true,
});
if (!tab?.id) {
console.error("No active tab found");
return null;
throw new Error("URL incorrecte");
}
const urlMatch = tab.url?.match(/\/(\d{2})-(\d{4})$/);
if (!urlMatch) {
console.error("Could not extract month and year from URL");
return null;
throw new Error("URL incorrecte");
}
const year = parseInt(urlMatch[2]!);
const month = parseInt(urlMatch[1]!);
try {
const [eventsQuery] = await chrome.scripting.executeScript({
target: { tabId: tab.id },
func: () => {
@@ -105,7 +103,7 @@ export async function extractData(): Promise<{
return events;
},
});
if (!eventsQuery?.result) return null;
if (!eventsQuery?.result) throw undefined;
return {
name: `gestime-${urlMatch[1]}-${urlMatch[2]}.ics`,
@@ -115,8 +113,9 @@ export async function extractData(): Promise<{
),
),
};
} catch (error) {
console.error("Error getting elements data:", error);
return null;
} catch {
throw new Error(
"Impossible d'extraires les données, contactez `hello@pihkaal.me`",
);
}
}