feat(legal): imprint & privacy notices, "Über MindSift"
- LEGAL_IMPRINT_/LEGAL_PRIVACY_ URL and Markdown (inline or *_FILE);
only http(s) URLs accepted
- /auth/status exposes legal info; public GET /legal/{imprint|privacy}
- Links on login/setup screen and in the settings footer: URL opens a new
tab, Markdown a reading modal; hidden when nothing is configured
- "Über MindSift" modal (version, license, repository) in settings and help
- Docs and compose/env examples
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a62b204e14
commit
d6c70d7a8e
17 files changed
+318
-2
No files matched your search
@@ -14,6 +14,7 @@ import {
|
||||
import { AuthStatus, SharingMode, User } from '../../lib/types';
|
||||
import { api, triggerHaptic } from '../../lib/api';
|
||||
import { ToggleSwitch } from '../../components/ToggleSwitch';
|
||||
import { LegalLinks } from '../../components/LegalLinks';
|
||||
|
||||
interface SetupAndAuthViewProps {
|
||||
authStatus: AuthStatus;
|
||||
@@ -330,6 +331,7 @@ export const SetupAndAuthView: React.FC<SetupAndAuthViewProps> = ({
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<LegalLinks legal={authStatus.legal} className="mt-4" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -574,6 +576,7 @@ export const SetupAndAuthView: React.FC<SetupAndAuthViewProps> = ({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<LegalLinks legal={authStatus.legal} className="mt-4" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
Flame,
|
||||
Check,
|
||||
} from 'lucide-react';
|
||||
import { AboutModal } from '../../components/AboutModal';
|
||||
|
||||
interface HelpViewProps {
|
||||
onBack?: () => void;
|
||||
@@ -55,6 +56,7 @@ interface DocCard {
|
||||
export const HelpView: React.FC<HelpViewProps> = ({ onBack }) => {
|
||||
const [activeCategory, setActiveCategory] = useState<HelpCategory>('all');
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [showAbout, setShowAbout] = useState(false);
|
||||
|
||||
// Documentation sections & cards data
|
||||
const cards: DocCard[] = useMemo(
|
||||
@@ -876,6 +878,13 @@ export const HelpView: React.FC<HelpViewProps> = ({ onBack }) => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-center pt-2">
|
||||
<button type="button" onClick={() => setShowAbout(true)} className="text-[11px] text-muted hover:text-main hover:underline underline-offset-2">
|
||||
Über MindSift
|
||||
</button>
|
||||
</div>
|
||||
{showAbout && <AboutModal onClose={() => setShowAbout(false)} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -20,11 +20,13 @@ import {
|
||||
Pencil,
|
||||
Copy,
|
||||
} from 'lucide-react';
|
||||
import { APIKey, User, UserTheme } from '../../lib/types';
|
||||
import { APIKey, AuthStatus, User, UserTheme } from '../../lib/types';
|
||||
import { api, triggerHaptic } from '../../lib/api';
|
||||
import { customThemeId, ThemeId, ThemeOption } from '../../lib/theme';
|
||||
import themeTemplateCss from '../../themes/theme-template.css?raw';
|
||||
import { UserAvatar, resizeImageToDataUrl } from '../../components/UserAvatar';
|
||||
import { LegalLinks } from '../../components/LegalLinks';
|
||||
import { AboutModal } from '../../components/AboutModal';
|
||||
|
||||
interface UserSettingsViewProps {
|
||||
currentUser: User;
|
||||
@@ -50,6 +52,11 @@ export const UserSettingsView: React.FC<UserSettingsViewProps> = ({
|
||||
onBack,
|
||||
}) => {
|
||||
const [section, setSection] = useState<UserSettingsSection>('profile');
|
||||
const [legal, setLegal] = useState<AuthStatus['legal']>();
|
||||
const [showAbout, setShowAbout] = useState(false);
|
||||
useEffect(() => {
|
||||
api.getAuthStatus().then((st) => setLegal(st.legal)).catch(() => {});
|
||||
}, []);
|
||||
|
||||
// --- Custom Theme Editor State ---
|
||||
const [themeEditId, setThemeEditId] = useState<string | null>(null); // null = new theme
|
||||
@@ -1227,6 +1234,14 @@ export const UserSettingsView: React.FC<UserSettingsViewProps> = ({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer: legal notices of this instance and project info */}
|
||||
<LegalLinks legal={legal} className="pt-4 border-t border-border">
|
||||
<button type="button" onClick={() => setShowAbout(true)} className="hover:text-main underline-offset-2 hover:underline">
|
||||
Über MindSift
|
||||
</button>
|
||||
</LegalLinks>
|
||||
{showAbout && <AboutModal onClose={() => setShowAbout(false)} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user