fix(theme): style share modal and inputs for dark mode compatibility
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 58s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 58s
This commit is contained in:
1 parent
0affb827a4
commit
1009487cce
4 files changed
+128
-39
No files matched your search
@@ -802,15 +802,15 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Invite User Form */}
|
{/* Invite User Form */}
|
||||||
<form onSubmit={handleAddMember} className="space-y-2.5 p-3 bg-canvas border border-border rounded-card">
|
<form onSubmit={handleAddMember} className="space-y-2.5 p-3 bg-panel-elevated border border-border rounded-card">
|
||||||
<div className="text-xs font-semibold text-main">User direkt einladen</div>
|
<div className="text-xs font-semibold text-main">User direkt einladen</div>
|
||||||
<div className="flex flex-col sm:flex-row gap-2">
|
<div className="flex flex-col sm:flex-row gap-2">
|
||||||
<select
|
<select
|
||||||
value={inviteTarget}
|
value={inviteTarget}
|
||||||
onChange={(e) => setInviteTarget(e.target.value)}
|
onChange={(e) => setInviteTarget(e.target.value)}
|
||||||
className="input-base text-xs flex-1"
|
className="input-field h-8 px-2.5 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-xs flex-1 cursor-pointer"
|
||||||
>
|
>
|
||||||
<option value="">User auswählen oder Name/E-Mail eingeben…</option>
|
<option value="" className="bg-panel text-muted">User auswählen oder Name/E-Mail eingeben…</option>
|
||||||
{collaborators
|
{collaborators
|
||||||
.filter(
|
.filter(
|
||||||
(u) =>
|
(u) =>
|
||||||
@@ -818,7 +818,7 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
|
|||||||
!(activeSpace.members || []).some((m) => m.userId === u.id)
|
!(activeSpace.members || []).some((m) => m.userId === u.id)
|
||||||
)
|
)
|
||||||
.map((u) => (
|
.map((u) => (
|
||||||
<option key={u.id} value={u.id}>
|
<option key={u.id} value={u.id} className="bg-panel text-main">
|
||||||
{u.displayName || u.username || u.email} ({u.username ? `@${u.username}` : u.email})
|
{u.displayName || u.username || u.email} ({u.username ? `@${u.username}` : u.email})
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
@@ -826,10 +826,10 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
|
|||||||
<select
|
<select
|
||||||
value={inviteRole}
|
value={inviteRole}
|
||||||
onChange={(e) => setInviteRole(e.target.value as 'editor' | 'viewer')}
|
onChange={(e) => setInviteRole(e.target.value as 'editor' | 'viewer')}
|
||||||
className="input-base text-xs w-full sm:w-36"
|
className="input-field h-8 px-2.5 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-xs w-full sm:w-36 cursor-pointer"
|
||||||
>
|
>
|
||||||
<option value="editor">Bearbeiten</option>
|
<option value="editor" className="bg-panel text-main">Bearbeiten</option>
|
||||||
<option value="viewer">Nur Lesen</option>
|
<option value="viewer" className="bg-panel text-main">Nur Lesen</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -840,7 +840,7 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
|
|||||||
placeholder="Oder Benutzername / E-Mail direkt eingeben…"
|
placeholder="Oder Benutzername / E-Mail direkt eingeben…"
|
||||||
value={inviteTarget}
|
value={inviteTarget}
|
||||||
onChange={(e) => setInviteTarget(e.target.value)}
|
onChange={(e) => setInviteTarget(e.target.value)}
|
||||||
className="input-base text-xs w-full"
|
className="input-field h-8 px-2.5 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-xs w-full"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import {
|
|||||||
Lock,
|
Lock,
|
||||||
Unlock,
|
Unlock,
|
||||||
Eye,
|
Eye,
|
||||||
|
Edit3,
|
||||||
Share,
|
Share,
|
||||||
Share2,
|
Share2,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
@@ -2881,19 +2882,19 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
{/* If current user is owner: can add shares and manage permissions */}
|
{/* If current user is owner: can add shares and manage permissions */}
|
||||||
{selectedDoc.isOwner !== false ? (
|
{selectedDoc.isOwner !== false ? (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<form onSubmit={handleAddShare} className="space-y-2.5 p-3 bg-canvas border border-border rounded-card">
|
<form onSubmit={handleAddShare} className="space-y-2.5 p-3 bg-panel-elevated border border-border rounded-card">
|
||||||
<div className="text-xs font-semibold text-main">Neuen Nutzer einladen / berechtigen</div>
|
<div className="text-xs font-semibold text-main">Neuen Nutzer einladen / berechtigen</div>
|
||||||
<div className="flex flex-col sm:flex-row gap-2">
|
<div className="flex flex-col sm:flex-row gap-2">
|
||||||
<select
|
<select
|
||||||
value={shareTargetEmailOrId}
|
value={shareTargetEmailOrId}
|
||||||
onChange={(e) => setShareTargetEmailOrId(e.target.value)}
|
onChange={(e) => setShareTargetEmailOrId(e.target.value)}
|
||||||
className="input-base text-xs flex-1"
|
className="input-field h-8 px-2.5 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-xs flex-1 cursor-pointer"
|
||||||
>
|
>
|
||||||
<option value="">Nutzer auswählen oder Email eingeben…</option>
|
<option value="" className="bg-panel text-muted">Nutzer auswählen oder Email eingeben…</option>
|
||||||
{collaborators
|
{collaborators
|
||||||
.filter((u) => u.id !== currentUser?.id && !docShares.some((s) => s.userId === u.id))
|
.filter((u) => u.id !== currentUser?.id && !docShares.some((s) => s.userId === u.id))
|
||||||
.map((u) => (
|
.map((u) => (
|
||||||
<option key={u.id} value={u.id}>
|
<option key={u.id} value={u.id} className="bg-panel text-main">
|
||||||
{u.displayName || u.email} ({u.email})
|
{u.displayName || u.email} ({u.email})
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
@@ -2901,10 +2902,10 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
<select
|
<select
|
||||||
value={sharePermission}
|
value={sharePermission}
|
||||||
onChange={(e) => setSharePermission(e.target.value as 'read' | 'write')}
|
onChange={(e) => setSharePermission(e.target.value as 'read' | 'write')}
|
||||||
className="input-base text-xs w-full sm:w-36"
|
className="input-field h-8 px-2.5 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-xs w-full sm:w-40 cursor-pointer"
|
||||||
>
|
>
|
||||||
<option value="read">Nur Lesen (read)</option>
|
<option value="read" className="bg-panel text-main">Nur Lesen (read)</option>
|
||||||
<option value="write">Schreiben (write)</option>
|
<option value="write" className="bg-panel text-main">Schreiben (write)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -2915,7 +2916,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
placeholder="Oder E-Mail-Adresse direkt eingeben…"
|
placeholder="Oder E-Mail-Adresse direkt eingeben…"
|
||||||
value={shareTargetEmailOrId}
|
value={shareTargetEmailOrId}
|
||||||
onChange={(e) => setShareTargetEmailOrId(e.target.value)}
|
onChange={(e) => setShareTargetEmailOrId(e.target.value)}
|
||||||
className="input-base text-xs w-full"
|
className="input-field h-8 px-2.5 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-xs w-full"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -2935,7 +2936,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="text-xs font-semibold text-main">Aktuelle Freigaben ({docShares.length})</div>
|
<div className="text-xs font-semibold text-main">Aktuelle Freigaben ({docShares.length})</div>
|
||||||
{docShares.length === 0 ? (
|
{docShares.length === 0 ? (
|
||||||
<div className="p-3 bg-canvas border border-border rounded-card text-xs text-muted text-center">
|
<div className="p-3 bg-panel-elevated border border-border rounded-card text-xs text-muted text-center">
|
||||||
Diese Notiz ist bisher noch mit niemandem geteilt.
|
Diese Notiz ist bisher noch mit niemandem geteilt.
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -2943,7 +2944,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
{docShares.map((share) => (
|
{docShares.map((share) => (
|
||||||
<div
|
<div
|
||||||
key={share.id || share.userId}
|
key={share.id || share.userId}
|
||||||
className="p-2.5 bg-canvas border border-border rounded-card flex items-center justify-between gap-3 text-xs"
|
className="p-2.5 bg-panel-elevated border border-border rounded-card flex items-center justify-between gap-3 text-xs"
|
||||||
>
|
>
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<div className="font-semibold text-main truncate">
|
<div className="font-semibold text-main truncate">
|
||||||
@@ -2958,11 +2959,11 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
<select
|
<select
|
||||||
value={share.permission}
|
value={share.permission}
|
||||||
onChange={(e) => handleUpdateSharePerm(share.userId, e.target.value as 'read' | 'write')}
|
onChange={(e) => handleUpdateSharePerm(share.userId, e.target.value as 'read' | 'write')}
|
||||||
className="input-base text-[11px] py-1 px-2 h-7"
|
className="input-field h-7 px-2 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-[11px] cursor-pointer"
|
||||||
disabled={sharingLoading}
|
disabled={sharingLoading}
|
||||||
>
|
>
|
||||||
<option value="read">Nur Lesen</option>
|
<option value="read" className="bg-panel text-main">Nur Lesen</option>
|
||||||
<option value="write">Schreiben</option>
|
<option value="write" className="bg-panel text-main">Schreiben</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@@ -2983,23 +2984,53 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
/* If current user is a collaborator */
|
/* If current user is a collaborator */
|
||||||
<div className="space-y-4 p-4 bg-canvas border border-border rounded-card text-xs">
|
<div className="space-y-3">
|
||||||
<div className="text-main font-semibold">Geteilte Notiz</div>
|
{/* Document & Owner Card */}
|
||||||
<div className="text-muted">
|
<div className="p-3 bg-panel-elevated border border-border rounded-card space-y-2">
|
||||||
Besitzer: <span className="text-main font-medium">{selectedDoc.ownerName || 'Unbekannt'}</span>
|
<div className="flex items-center justify-between text-xs">
|
||||||
</div>
|
<span className="text-muted">Eigentümer der Notiz:</span>
|
||||||
<div className="text-muted">
|
<span className="font-semibold text-main flex items-center gap-1.5">
|
||||||
Deine Berechtigung:{' '}
|
<span className="w-5 h-5 rounded-full bg-accent/20 text-accent text-[10px] font-bold flex items-center justify-center">
|
||||||
<span className="text-accent font-semibold">
|
{(selectedDoc.ownerName || 'U').slice(0, 1).toUpperCase()}
|
||||||
{selectedDoc.permission === 'write' ? 'Schreibzugriff (Bearbeiten erlaubt)' : 'Nur Lesezugriff'}
|
</span>
|
||||||
</span>
|
<span>{selectedDoc.ownerName || 'Unbekannt'}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="pt-2 border-t border-border">
|
{/* Permission Card */}
|
||||||
|
{selectedDoc.permission === 'write' ? (
|
||||||
|
<div className="p-3 bg-emerald-500/10 border border-emerald-500/30 rounded-card flex items-start gap-3">
|
||||||
|
<div className="w-8 h-8 rounded-btn bg-emerald-500/20 text-emerald-600 dark:text-emerald-400 flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||||
|
<Edit3 className="w-4 h-4" />
|
||||||
|
</div>
|
||||||
|
<div className="text-xs space-y-0.5">
|
||||||
|
<div className="font-semibold text-emerald-600 dark:text-emerald-400">Schreibzugriff aktiv</div>
|
||||||
|
<div className="text-muted">
|
||||||
|
Du hast Bearbeitungsrechte für diese Notiz und kannst Inhalte in Echtzeit anpassen.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="p-3 bg-accent/10 border border-accent/30 rounded-card flex items-start gap-3">
|
||||||
|
<div className="w-8 h-8 rounded-btn bg-accent/20 text-accent flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||||
|
<Eye className="w-4 h-4" />
|
||||||
|
</div>
|
||||||
|
<div className="text-xs space-y-0.5">
|
||||||
|
<div className="font-semibold text-accent">Nur Lesezugriff</div>
|
||||||
|
<div className="text-muted">
|
||||||
|
Du kannst diese Notiz ansehen und durchsuchen, aber keine Änderungen an den Inhalten vornehmen.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Action: Leave Share */}
|
||||||
|
<div className="pt-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleLeaveShare}
|
onClick={handleLeaveShare}
|
||||||
className="btn-danger h-8 px-3 text-xs flex items-center gap-1.5"
|
className="w-full btn-action h-8 px-3 text-xs text-status-err hover:bg-status-err-bg border border-status-err-border rounded-btn flex items-center justify-center gap-1.5 transition-colors"
|
||||||
>
|
>
|
||||||
<Trash2 className="w-3.5 h-3.5" />
|
<Trash2 className="w-3.5 h-3.5" />
|
||||||
<span>Notiz aus meinem Workspace entfernen</span>
|
<span>Notiz aus meinem Workspace entfernen</span>
|
||||||
@@ -3012,9 +3043,9 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowShareModal(false)}
|
onClick={() => setShowShareModal(false)}
|
||||||
className="btn-secondary h-8 px-4 text-xs"
|
className="btn-action h-8 px-4 text-xs font-medium"
|
||||||
>
|
>
|
||||||
Fertig
|
Schließen
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+52
-4
@@ -178,8 +178,54 @@ body {
|
|||||||
border-color: var(--border-danger);
|
border-color: var(--border-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zentrales Texteingabefeld */
|
/* Sekundärer Button */
|
||||||
.input-field {
|
.btn-secondary {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
height: 1.75rem;
|
||||||
|
padding-left: 0.75rem;
|
||||||
|
padding-right: 0.75rem;
|
||||||
|
background-color: var(--bg-panel-elevated);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--radius-btn);
|
||||||
|
color: var(--text-main);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 120ms ease;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: var(--bg-panel-hover);
|
||||||
|
border-color: var(--border-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gefahren-/Löschen-Button */
|
||||||
|
.btn-danger {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
height: 1.75rem;
|
||||||
|
padding-left: 0.75rem;
|
||||||
|
padding-right: 0.75rem;
|
||||||
|
background-color: var(--bg-danger);
|
||||||
|
border: 1px solid var(--border-danger);
|
||||||
|
border-radius: var(--radius-btn);
|
||||||
|
color: var(--color-danger);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 120ms ease;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.btn-danger:hover {
|
||||||
|
filter: brightness(1.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zentrales Texteingabefeld & Aliasse */
|
||||||
|
.input-field,
|
||||||
|
.input-base {
|
||||||
background-color: var(--bg-input);
|
background-color: var(--bg-input);
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: var(--radius-input);
|
border-radius: var(--radius-input);
|
||||||
@@ -187,11 +233,13 @@ body {
|
|||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
transition: border-color 120ms ease;
|
transition: border-color 120ms ease;
|
||||||
}
|
}
|
||||||
.input-field:focus {
|
.input-field:focus,
|
||||||
|
.input-base:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: var(--accent-primary);
|
border-color: var(--accent-primary);
|
||||||
}
|
}
|
||||||
.input-field::placeholder {
|
.input-field::placeholder,
|
||||||
|
.input-base::placeholder {
|
||||||
color: var(--text-faint);
|
color: var(--text-faint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,11 @@ export function setActiveTheme(themeId: ThemeId): void {
|
|||||||
}
|
}
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
document.documentElement.setAttribute('data-theme', themeId);
|
document.documentElement.setAttribute('data-theme', themeId);
|
||||||
|
if (themeId !== 'light') {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +93,11 @@ export function initThemeOnBoot(): ThemeId {
|
|||||||
const active = getActiveTheme();
|
const active = getActiveTheme();
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
document.documentElement.setAttribute('data-theme', active);
|
document.documentElement.setAttribute('data-theme', active);
|
||||||
|
if (active !== 'light') {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user