Introduce dark mode

This commit is contained in:
Dominik Schröter 2024-10-07 22:14:05 +02:00
parent cc04527e36
commit b47f062730
8 changed files with 63 additions and 47 deletions

View file

@ -1,13 +1,13 @@
<!doctype html>
<html lang="en">
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Paperless GPT</title>
</head>
<body>
<body class="bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-200">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
</html>

View file

@ -185,22 +185,20 @@ const DocumentProcessor: React.FC = () => {
if (loading) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="text-xl font-semibold">Loading documents...</div>
<div className="flex items-center justify-center min-h-screen bg-white dark:bg-gray-900">
<div className="text-xl font-semibold text-gray-800 dark:text-gray-200">Loading documents...</div>
</div>
);
}
return (
<div className="max-w-5xl mx-auto p-6">
<div className="max-w-5xl mx-auto p-6 bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-200">
<header className="text-center">
<h1 className="text-4xl font-bold mb-8 text-gray-800">
Paperless GPT
</h1>
<h1 className="text-4xl font-bold mb-8">Paperless GPT</h1>
</header>
{error && (
<div className="mb-4 p-4 bg-red-100 text-red-800 rounded">
<div className="mb-4 p-4 bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200 rounded">
{error}
</div>
)}
@ -246,4 +244,4 @@ const DocumentProcessor: React.FC = () => {
);
};
export default DocumentProcessor;
export default DocumentProcessor;

View file

@ -6,9 +6,9 @@ interface DocumentCardProps {
}
const DocumentCard: React.FC<DocumentCardProps> = ({ document }) => (
<div className="bg-white shadow-lg shadow-blue-500/50 rounded-md p-4 relative group overflow-hidden">
<h3 className="text-lg font-semibold text-gray-800">{document.title}</h3>
<p className="text-sm text-gray-600 mt-2 truncate">
<div className="bg-white dark:bg-gray-800 shadow-lg shadow-blue-500/50 rounded-md p-4 relative group overflow-hidden">
<h3 className="text-lg font-semibold text-gray-800 dark:text-gray-200">{document.title}</h3>
<p className="text-sm text-gray-600 dark:text-gray-400 mt-2 truncate">
{document.content.length > 100
? `${document.content.substring(0, 100)}...`
: document.content}
@ -17,21 +17,21 @@ const DocumentCard: React.FC<DocumentCardProps> = ({ document }) => (
{document.tags.map((tag) => (
<span
key={tag}
className="bg-blue-100 text-blue-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full"
className="bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full"
>
{tag}
</span>
))}
</div>
<div className="absolute inset-0 bg-black bg-opacity-50 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center p-4 rounded-md">
<div className="text-sm text-white p-2 bg-gray-800 rounded-md w-full max-h-full overflow-y-auto">
<div className="absolute inset-0 bg-black bg-opacity-50 dark:bg-opacity-70 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center p-4 rounded-md">
<div className="text-sm text-white p-2 bg-gray-800 dark:bg-gray-900 rounded-md w-full max-h-full overflow-y-auto">
<h3 className="text-lg font-semibold text-white">{document.title}</h3>
<p className="mt-2 whitespace-pre-wrap">{document.content}</p>
<div className="mt-4">
{document.tags.map((tag) => (
<span
key={tag}
className="bg-blue-100 text-blue-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full"
className="bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full"
>
{tag}
</span>

View file

@ -26,19 +26,19 @@ const DocumentsToProcess: React.FC<DocumentsToProcessProps> = ({
}) => (
<section>
<div className="flex justify-between items-center mb-6">
<h2 className="text-2xl font-semibold text-gray-700">Documents to Process</h2>
<h2 className="text-2xl font-semibold text-gray-700 dark:text-gray-200">Documents to Process</h2>
<div className="flex space-x-2">
<button
onClick={onReload}
disabled={processing}
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 focus:outline-none"
className="bg-blue-600 text-white dark:bg-blue-800 dark:text-gray-200 px-4 py-2 rounded hover:bg-blue-700 dark:hover:bg-blue-900 focus:outline-none"
>
<ArrowPathIcon className="h-5 w-5" />
</button>
<button
onClick={onProcess}
disabled={processing}
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 focus:outline-none"
className="bg-blue-600 text-white dark:bg-blue-800 dark:text-gray-200 px-4 py-2 rounded hover:bg-blue-700 dark:hover:bg-blue-900 focus:outline-none"
>
{processing ? "Processing..." : "Generate Suggestions"}
</button>
@ -51,16 +51,18 @@ const DocumentsToProcess: React.FC<DocumentsToProcessProps> = ({
type="checkbox"
checked={generateTitles}
onChange={(e) => setGenerateTitles(e.target.checked)}
className="dark:bg-gray-700 dark:border-gray-600"
/>
<span>Generate Titles</span>
<span className="text-gray-700 dark:text-gray-200">Generate Titles</span>
</label>
<label className="flex items-center space-x-2">
<input
type="checkbox"
checked={generateTags}
onChange={(e) => setGenerateTags(e.target.checked)}
className="dark:bg-gray-700 dark:border-gray-600"
/>
<span>Generate Tags</span>
<span className="text-gray-700 dark:text-gray-200">Generate Tags</span>
</label>
</div>

View file

@ -12,11 +12,11 @@ const NoDocuments: React.FC<NoDocumentsProps> = ({
onReload,
processing,
}) => (
<div className="flex flex-col items-center justify-center min-h-screen">
<div className="flex flex-col items-center justify-center min-h-screen bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-200">
<p className="text-xl font-semibold mb-4">
No documents found with filter tag{" "}
{filterTag && (
<span className="bg-blue-100 text-blue-800 text-sm font-medium px-2.5 py-0.5 rounded-full">
<span className="bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-sm font-medium px-2.5 py-0.5 rounded-full">
{filterTag}
</span>
)}
@ -25,7 +25,7 @@ const NoDocuments: React.FC<NoDocumentsProps> = ({
<button
onClick={onReload}
disabled={processing}
className="flex items-center bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 focus:outline-none"
className="flex items-center bg-blue-600 dark:bg-blue-800 text-white dark:text-gray-200 px-4 py-2 rounded hover:bg-blue-700 dark:hover:bg-blue-900 focus:outline-none"
>
Reload
<ArrowPathIcon className="h-5 w-5 ml-2" />

View file

@ -1,6 +1,6 @@
import React, { Fragment } from "react";
import { Dialog, DialogTitle, Transition } from "@headlessui/react";
import { CheckCircleIcon } from "@heroicons/react/24/outline";
import React, { Fragment } from "react";
interface SuccessModalProps {
isOpen: boolean;
@ -25,7 +25,7 @@ const SuccessModal: React.FC<SuccessModalProps> = ({ isOpen, onClose }) => (
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
<div className="fixed inset-0 bg-gray-500 dark:bg-gray-800 bg-opacity-75 transition-opacity" />
</Transition.Child>
<span
@ -44,25 +44,24 @@ const SuccessModal: React.FC<SuccessModalProps> = ({ isOpen, onClose }) => (
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div className="inline-block align-bottom bg-white rounded-lg px-6 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div className="inline-block align-bottom bg-white dark:bg-gray-900 rounded-lg px-6 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div className="sm:flex sm:items-start">
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100 sm:mx-0 sm:h-12 sm:w-12">
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100 dark:bg-green-900 sm:mx-0 sm:h-12 sm:w-12">
<CheckCircleIcon
className="h-6 w-6 text-green-600"
className="h-6 w-6 text-green-600 dark:text-green-400"
aria-hidden="true"
/>
</div>
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<DialogTitle
as="h3"
className="text-lg leading-6 font-medium text-gray-900"
className="text-lg leading-6 font-medium text-gray-900 dark:text-gray-200"
>
Documents Updated
</DialogTitle>
<div className="mt-2">
<p className="text-sm text-gray-500">
The documents have been successfully updated with the
new titles and tags.
<p className="text-sm text-gray-500 dark:text-gray-400">
The documents have been successfully updated with the new titles and tags.
</p>
</div>
</div>
@ -70,7 +69,7 @@ const SuccessModal: React.FC<SuccessModalProps> = ({ isOpen, onClose }) => (
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<button
onClick={onClose}
className="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm"
className="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 dark:bg-green-700 text-base font-medium text-white hover:bg-green-700 dark:hover:bg-green-800 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm"
>
OK
</button>

View file

@ -19,13 +19,13 @@ const SuggestionCard: React.FC<SuggestionCardProps> = ({
}) => {
const document = suggestion.original_document;
return (
<div className="bg-white shadow-lg shadow-blue-500/50 rounded-md p-4 relative flex flex-col justify-between h-full">
<div className="bg-white dark:bg-gray-800 shadow-lg shadow-blue-500/50 rounded-md p-4 relative flex flex-col justify-between h-full">
<div className="flex items-center group relative">
<div className="relative">
<h3 className="text-lg font-semibold text-gray-800">
<h3 className="text-lg font-semibold text-gray-800 dark:text-gray-200">
{document.title}
</h3>
<p className="text-sm text-gray-600 mt-2 truncate">
<p className="text-sm text-gray-600 dark:text-gray-400 mt-2 truncate">
{document.content.length > 40
? `${document.content.substring(0, 40)}...`
: document.content}
@ -34,15 +34,15 @@ const SuggestionCard: React.FC<SuggestionCardProps> = ({
{document.tags.map((tag) => (
<span
key={tag}
className="bg-blue-100 text-blue-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full"
className="bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full"
>
{tag}
</span>
))}
</div>
</div>
<div className="absolute inset-0 bg-black bg-opacity-50 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center p-4 rounded-md">
<div className="text-sm text-white p-2 bg-gray-800 rounded-md w-full max-h-full overflow-y-auto">
<div className="absolute inset-0 bg-black bg-opacity-50 dark:bg-opacity-70 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center p-4 rounded-md">
<div className="text-sm text-white p-2 bg-gray-800 dark:bg-gray-900 rounded-md w-full max-h-full overflow-y-auto">
<p className="mt-2 whitespace-pre-wrap">{document.content}</p>
</div>
</div>
@ -52,7 +52,7 @@ const SuggestionCard: React.FC<SuggestionCardProps> = ({
type="text"
value={suggestion.suggested_title || ""}
onChange={(e) => onTitleChange(suggestion.id, e.target.value)}
className="w-full border border-gray-300 rounded px-2 py-1 mt-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
className="w-full border border-gray-300 dark:border-gray-600 rounded px-2 py-1 mt-2 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:text-gray-200"
/>
<div className="mt-4">
<ReactTags
@ -79,6 +79,23 @@ const SuggestionCard: React.FC<SuggestionCardProps> = ({
onDelete={(index) => onTagDeletion(suggestion.id, index)}
allowNew={true}
placeholderText="Add a tag"
classNames={{
root: "react-tags dark:bg-gray-800",
rootIsActive: "is-active",
rootIsDisabled: "is-disabled",
rootIsInvalid: "is-invalid",
label: "react-tags__label",
tagList: "react-tags__list",
tagListItem: "react-tags__list-item",
tag: "react-tags__tag dark:bg-blue-900 dark:text-blue-200",
tagName: "react-tags__tag-name",
comboBox: "react-tags__combobox dark:bg-gray-700 dark:text-gray-200",
input: "react-tags__combobox-input dark:bg-gray-700 dark:text-gray-200",
listBox: "react-tags__listbox dark:bg-gray-700 dark:text-gray-200",
option: "react-tags__listbox-option dark:bg-gray-700 dark:text-gray-200 hover:bg-blue-500 dark:hover:bg-blue-800",
optionIsActive: "is-active",
highlight: "react-tags__highlight dark:bg-gray-800",
}}
/>
</div>
</div>

View file

@ -24,7 +24,7 @@ const SuggestionsReview: React.FC<SuggestionsReviewProps> = ({
updating,
}) => (
<section>
<h2 className="text-2xl font-semibold text-gray-700 mb-6">
<h2 className="text-2xl font-semibold text-gray-700 dark:text-gray-200 mb-6">
Review and Edit Suggested Titles
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
@ -42,7 +42,7 @@ const SuggestionsReview: React.FC<SuggestionsReviewProps> = ({
<div className="flex justify-end space-x-4 mt-6">
<button
onClick={onBack}
className="bg-gray-200 text-gray-700 px-4 py-2 rounded hover:bg-gray-300 focus:outline-none"
className="bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 px-4 py-2 rounded hover:bg-gray-300 dark:hover:bg-gray-600 focus:outline-none"
>
Back
</button>
@ -51,8 +51,8 @@ const SuggestionsReview: React.FC<SuggestionsReviewProps> = ({
disabled={updating}
className={`${
updating
? "bg-green-400 cursor-not-allowed"
: "bg-green-600 hover:bg-green-700"
? "bg-green-400 dark:bg-green-600 cursor-not-allowed"
: "bg-green-600 dark:bg-green-700 hover:bg-green-700 dark:hover:bg-green-800"
} text-white px-4 py-2 rounded focus:outline-none`}
>
{updating ? "Updating..." : "Apply Suggestions"}