mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Add About & Privacy and Donate modals (M6, §01)
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* About & Help modal body (spec §01B/§01C).
|
||||
*
|
||||
* Rendered inside ModalShell — no backdrop, close button, or focus trap here;
|
||||
* the shell owns all of that (docs/architecture/03 → Layer 3). This component
|
||||
* is pure content: app identity, keyboard shortcuts (§01D), and privacy posture
|
||||
* (SOUL.md — local-only, no accounts, no telemetry).
|
||||
*/
|
||||
|
||||
import styles from './AboutModal.module.css';
|
||||
|
||||
/** True when the user agent is macOS / iOS — drives the Cmd vs. Ctrl label. */
|
||||
const isMac = /Mac|iPhone|iPad|iPod/.test(navigator.platform);
|
||||
const mod = isMac ? '⌘' : 'Ctrl';
|
||||
|
||||
/** Keyboard shortcut rows sourced from spec §01D. */
|
||||
const SHORTCUTS: readonly { keys: string; action: string }[] = [
|
||||
{ keys: `${mod}+Shift+N`, action: 'Create a new snippet' },
|
||||
{ keys: `${mod}+K`, action: 'Toggle the Datasets manager' },
|
||||
{ keys: `${mod}+S`, action: 'Publish the current snippet draft' },
|
||||
{ keys: `${mod}+,`, action: 'Open editor settings' },
|
||||
{ keys: 'Esc', action: 'Close the active modal' },
|
||||
];
|
||||
|
||||
export function AboutModal() {
|
||||
return (
|
||||
<div className={styles.about}>
|
||||
{/* Identity */}
|
||||
<section className={styles.section}>
|
||||
<h3 className={styles.heading}>Astrolabe</h3>
|
||||
<p className={styles.body}>
|
||||
v<span className={styles.version}>{__APP_VERSION__}</span>
|
||||
</p>
|
||||
<p className={styles.body}>
|
||||
A local-first workspace for authoring, organizing, and previewing Vega-Lite charts. Edit
|
||||
JSON, see the chart update live, and keep a personal library of snippets — with no
|
||||
account, no server, and full offline support.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Keyboard shortcuts */}
|
||||
<section className={styles.section}>
|
||||
<h3 className={styles.heading}>Keyboard shortcuts</h3>
|
||||
<table className={styles.shortcuts} aria-label="Keyboard shortcuts">
|
||||
<tbody>
|
||||
{SHORTCUTS.map(({ keys, action }) => (
|
||||
<tr key={keys} className={styles.row}>
|
||||
<td className={styles.keys}>
|
||||
<kbd className={styles.kbd}>{keys}</kbd>
|
||||
</td>
|
||||
<td className={styles.action}>{action}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
{/* Privacy */}
|
||||
<section className={styles.section}>
|
||||
<h3 className={styles.heading}>Privacy</h3>
|
||||
<p className={styles.body}>
|
||||
Astrolabe runs entirely in your browser. Your snippets, datasets, and settings are stored
|
||||
locally and never leave your machine.
|
||||
</p>
|
||||
<ul className={styles.list}>
|
||||
<li>No account, no sign-in, no server-side storage.</li>
|
||||
<li>No telemetry, no analytics, no tracking of any kind.</li>
|
||||
<li>
|
||||
The only outbound network requests are ones you create: URL-sourced datasets you add
|
||||
yourself.
|
||||
</li>
|
||||
<li>After the first load, the app works fully offline.</li>
|
||||
<li>Use Import / Export to move your library between devices.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user