44 lines
2.3 KiB
TypeScript
44 lines
2.3 KiB
TypeScript
import { useState } from "react";
|
||
import { Download } from "lucide-react";
|
||
import { applyUpdate, installApp, useOnline, usePwa } from "../pwa/client";
|
||
import { Button } from "./design-system/primitives";
|
||
import { Modal } from "./design-system/Modal";
|
||
|
||
export function InstallApp() {
|
||
const { enabled, installed, installPrompt } = usePwa();
|
||
const [help, setHelp] = useState(false);
|
||
if (!enabled || installed) return null;
|
||
return <>
|
||
<Button variant="primary" onClick={() => { if (installPrompt) void installApp(); else setHelp(true); }}><Download size={16} aria-hidden="true" />Install app</Button>
|
||
{help && <Modal id="install-app" size="compact" title="Install app" onClose={() => setHelp(false)}>
|
||
<div className="ds-form-stack">
|
||
<p><strong>iPhone or iPad:</strong> open the Share menu, then choose Add to Home Screen.</p>
|
||
<p><strong>Mac Safari:</strong> choose File → Add to Dock.</p>
|
||
<p><strong>Chrome or Edge:</strong> use the install icon in the address bar, or Install app in the browser menu.</p>
|
||
<p className="ds-supporting-copy">An internet connection is required to load and save habits.</p>
|
||
<div className="ds-actions"><Button onClick={() => setHelp(false)}>Got it</Button></div>
|
||
</div>
|
||
</Modal>}
|
||
</>;
|
||
}
|
||
|
||
export function PwaStatus() {
|
||
const online = useOnline();
|
||
const { updateReady, error } = usePwa();
|
||
const [confirmUpdate, setConfirmUpdate] = useState(false);
|
||
return <>
|
||
{!online && <div className="ds-form-feedback" role="status">You’re offline. Reconnect to load or save your habits. Changes are not queued.</div>}
|
||
{error && <div className="ds-form-feedback" role="status">{error}</div>}
|
||
{updateReady && <div className="ds-action-row" role="status">
|
||
<span>A new version of Mina Habits is ready.</span>
|
||
<Button variant="secondary" onClick={() => setConfirmUpdate(true)}>Update app</Button>
|
||
</div>}
|
||
{confirmUpdate && <Modal id="update-app" size="compact" title="Ready to update?" onClose={() => setConfirmUpdate(false)}>
|
||
<div className="ds-form-stack">
|
||
<p>This window will reload. Save any unfinished changes first.</p>
|
||
<div className="ds-actions"><Button onClick={applyUpdate}>Reload and update</Button><Button variant="text" onClick={() => setConfirmUpdate(false)}>Later</Button></div>
|
||
</div>
|
||
</Modal>}
|
||
</>;
|
||
}
|