Skip to content
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
11 changes: 10 additions & 1 deletion components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { FileText, Clipboard, Upload, Save } from "lucide-react";
import { FileText, Clipboard, Upload, Save, RotateCcw } from "lucide-react";
import { ThemeToggle } from "./ThemeToggle";

interface HeaderProps {
Expand All @@ -8,6 +8,7 @@ interface HeaderProps {
handleFileUpload: (e: React.ChangeEvent<HTMLInputElement>) => void;
handleImportFileClick: () => void;
handleExport: () => void;
resetProtocol: () => void;
}

export const Header = ({
Expand All @@ -16,6 +17,7 @@ export const Header = ({
handleFileUpload,
handleImportFileClick,
handleExport,
resetProtocol,
}: HeaderProps) => {
return (
<header className="bg-white dark:bg-slate-950 border-b border-slate-200 dark:border-slate-800 sticky top-0 z-10 transition-colors">
Expand All @@ -30,6 +32,13 @@ export const Header = ({
</div>
<div className="flex gap-2">
<ThemeToggle />
<button
onClick={resetProtocol}
className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/20 hover:bg-red-100 dark:hover:bg-red-900/30 border border-transparent rounded-lg transition-colors"
title="Protokoll zurücksetzen"
>
<RotateCcw size={16} /> <span className="hidden sm:inline">Reset</span>
</button>
<button
onClick={handlePasteFromClipboard}
className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-slate-600 dark:text-slate-300 bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-800 rounded-lg transition-colors"
Expand Down
2 changes: 2 additions & 0 deletions components/ProtocolEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function ProtocolEditor({
updatePoint,
removePoint,
handleDragEnd,
resetProtocol,
} = useProtocol();

const sensors = useSensors(
Expand All @@ -73,6 +74,7 @@ export function ProtocolEditor({
handleFileUpload={handleFileUpload}
handleImportFileClick={handleImportFileClick}
handleExport={handleExport}
resetProtocol={resetProtocol}
/>

<main className="max-w-6xl mx-auto px-6 py-8 space-y-8">
Expand Down
63 changes: 62 additions & 1 deletion hooks/useProtocol.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { useState, useRef } from "react";
import { useState, useRef, useEffect } from "react";
import yaml from "js-yaml";
import { SessionItem, ProtocolData } from "@/common/types";
import { sessionObjectToArray, sessionArrayToObject } from "@/common/utils";
import { DragEndEvent } from "@dnd-kit/core";
import { arrayMove } from "@dnd-kit/sortable";

const STORAGE_KEY = "fsr-protocol-data";

export const useProtocol = () => {
const [isLoaded, setIsLoaded] = useState(false);
const [fsrMembers, setFsrMembers] = useState<string[]>([]);
const [guests, setGuests] = useState<string[]>([]);
const [protocolant, setProtocolant] = useState<string[]>([]);
Expand All @@ -18,6 +21,63 @@ export const useProtocol = () => {
const [sessionItems, setSessionItems] = useState<SessionItem[]>([]);
const fileInputRef = useRef<HTMLInputElement>(null);

// Load from LocalStorage on mount
useEffect(() => {
const savedData = localStorage.getItem(STORAGE_KEY);
if (savedData) {
try {
const parsed = JSON.parse(savedData);
setFsrMembers(parsed.fsrMembers || []);
setGuests(parsed.guests || []);
setProtocolant(parsed.protocolant || []);
setMeta(
parsed.meta || {
Date: new Date().toISOString().split("T")[0],
Start: "16:30",
Ende: "17:30",
}
);
setSessionItems(parsed.sessionItems || []);
} catch (e) {
console.error("Failed to load protocol data", e);
}
}
setIsLoaded(true);
}, []);

// Save to LocalStorage on change
useEffect(() => {
if (!isLoaded) return;
const dataToSave = {
fsrMembers,
guests,
protocolant,
meta,
sessionItems,
};
localStorage.setItem(STORAGE_KEY, JSON.stringify(dataToSave));
}, [fsrMembers, guests, protocolant, meta, sessionItems, isLoaded]);

const resetProtocol = () => {
if (
!window.confirm(
"Möchtest du das Protokoll wirklich zurücksetzen? Alle ungespeicherten Daten gehen verloren."
)
) {
return;
}
localStorage.removeItem(STORAGE_KEY);
setFsrMembers([]);
setGuests([]);
setProtocolant([]);
setMeta({
Date: new Date().toISOString().split("T")[0],
Start: "16:30",
Ende: "17:30",
});
setSessionItems([]);
};

const processYamlContent = (content: string) => {
try {
const parsed = yaml.load(content) as ProtocolData;
Expand Down Expand Up @@ -215,5 +275,6 @@ export const useProtocol = () => {
updatePoint,
removePoint,
handleDragEnd,
resetProtocol,
};
};