feat(web): migrate PastebinView to cocotte ui (Wave A drill) -- web/src/views/PastebinView.tsx
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a46fb8dfa0
commit
9ad22c5e6d
1 changed files with 41 additions and 27 deletions
|
|
@ -1,13 +1,14 @@
|
|||
import { getPastebin, type PastebinTemplate } from '../api';
|
||||
import { usePoll } from '../usePoll';
|
||||
import { Card, VStack, HStack, Button, Pill, Muted, ErrText, Title } from '../ui';
|
||||
|
||||
/** Read-only view of the live 🌹 canon templates (synced from Notes by macsync).
|
||||
* Editing happens in the Apple Note; this surfaces what the engine will render. */
|
||||
export function PastebinView(): JSX.Element {
|
||||
const { data, error, loading } = usePoll<{ templates: PastebinTemplate[] }>(() => getPastebin(), 60000);
|
||||
|
||||
if (error) return <div className="err">{error}</div>;
|
||||
if (loading || !data) return <div className="muted">Loading pastebin…</div>;
|
||||
if (error) return <ErrText>{error}</ErrText>;
|
||||
if (loading || !data) return <Muted>Loading pastebin…</Muted>;
|
||||
|
||||
const sync = (): void => {
|
||||
alert('Sync from macsync (iNotes) requested — macsync pushes updates to /pastebin via webhook. Re-polling now.');
|
||||
|
|
@ -15,34 +16,47 @@ export function PastebinView(): JSX.Element {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="view-stack">
|
||||
<section className="card market-bar">
|
||||
<div className="market-bar__field">
|
||||
<span className="card__title" style={{ marginBottom: 4 }}>🌹 Pastebin Editor — macsync + Apple Notes</span>
|
||||
<span className="muted">
|
||||
🌹 canon — {data.templates.length} templates · live-synced from the Apple Note (edit in Notes, macsync pushes). Apply from Triage/Detail composer.
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
||||
<span className="pill pill--hold">live poll</span>
|
||||
<button type="button" className="btn btn--sm" onClick={sync}>⟳ Sync from macsync (iNotes)</button>
|
||||
</div>
|
||||
</section>
|
||||
<VStack $gap={16}>
|
||||
<Card>
|
||||
<HStack $justify="space-between" $align="start" $gap={16}>
|
||||
<VStack $gap={4}>
|
||||
<Title>🌹 Pastebin Editor — macsync + Apple Notes</Title>
|
||||
<Muted>
|
||||
🌹 canon — {data.templates.length} templates · live-synced from the Apple Note (edit in Notes, macsync pushes). Apply from Triage/Detail composer.
|
||||
</Muted>
|
||||
</VStack>
|
||||
<HStack $gap={10}>
|
||||
<Pill $tone="accent">live poll</Pill>
|
||||
<Button type="button" $variant="primary" onClick={sync}>⟳ Sync from macsync (iNotes)</Button>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Card>
|
||||
|
||||
{data.templates.length === 0 ? (
|
||||
<div className="err">No templates — macsync unreachable or the note is empty. Sends hold until available.</div>
|
||||
<ErrText>No templates — macsync unreachable or the note is empty. Sends hold until available.</ErrText>
|
||||
) : null}
|
||||
|
||||
<div className="held-list">
|
||||
{data.templates.map((t) => (
|
||||
<div key={t.key} className="held">
|
||||
<div className="held__top">
|
||||
<span className="held__handle mono" style={{ color: 'var(--accent)' }}>{t.key}</span>
|
||||
</div>
|
||||
<div className="pb__body">{t.body}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<Card>
|
||||
<VStack $gap={10}>
|
||||
{data.templates.map((t) => (
|
||||
<HStack key={t.key} $gap={12} $align="start">
|
||||
<span
|
||||
style={{
|
||||
fontFamily: 'ui-monospace, Menlo, monospace',
|
||||
fontWeight: 600,
|
||||
color: 'var(--theme-color-primary-main)',
|
||||
width: '5.5rem',
|
||||
flexShrink: 0,
|
||||
textAlign: 'right',
|
||||
}}
|
||||
>
|
||||
{t.key}
|
||||
</span>
|
||||
<span style={{ whiteSpace: 'pre-wrap', lineHeight: 1.4 }}>{t.body}</span>
|
||||
</HStack>
|
||||
))}
|
||||
</VStack>
|
||||
</Card>
|
||||
</VStack>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue