Fix plan days with no chapters, add a way out of ink mode, harden ntfy reminders
Build and Push Docker Image / build-and-push (push) Failing after 19s
Build and Push Docker Image / build-and-push (push) Failing after 19s
Plans can no longer have more days than chapters (existing ones heal), and opening a plan never strands the Reader on an empty day. The Reader shows Done drawing while inking (Escape also exits). Reminders use the user's own timezone, send within a 3 hour grace window, and Settings has a Send test notification button. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ecb1c701fa
commit
297f2c7e84
14 files changed
+335
-58
No files matched your search
@@ -8,6 +8,7 @@ import {
|
||||
changePassword,
|
||||
updateProfile,
|
||||
updateReminderSettings,
|
||||
sendReminderTest,
|
||||
} from '../syncService.js';
|
||||
import { exportJournalDocx, printJournalPdf } from '../utils/journalExport.js';
|
||||
|
||||
@@ -120,11 +121,20 @@ export default function SettingsPage() {
|
||||
window.setTimeout(() => setPodcastNameSaved(false), 2500);
|
||||
};
|
||||
|
||||
const [reminderTest, setReminderTest] = useState({ busy: false, ok: false, message: '' });
|
||||
const testReminder = async () => {
|
||||
setReminderTest({ busy: true, ok: false, message: '' });
|
||||
const result = await sendReminderTest({ ntfyTopic: reminderForm.ntfyTopic, ntfyUrl: reminderForm.ntfyUrl });
|
||||
setReminderTest(result.ok
|
||||
? { busy: false, ok: true, message: 'Sent. Check your ntfy app or the topic page in a browser.' }
|
||||
: { busy: false, ok: false, message: result.error ?? 'Could not send the test.' });
|
||||
};
|
||||
|
||||
const submitReminderSettings = async (e) => {
|
||||
e.preventDefault();
|
||||
setReminderError('');
|
||||
setReminderBusy(true);
|
||||
const result = await updateReminderSettings(reminderForm);
|
||||
const result = await updateReminderSettings({ ...reminderForm, reminderTz: Intl.DateTimeFormat().resolvedOptions().timeZone });
|
||||
setReminderBusy(false);
|
||||
if (!result.ok) {
|
||||
setReminderError(result.error ?? 'Failed to save reminder settings.');
|
||||
@@ -334,13 +344,26 @@ export default function SettingsPage() {
|
||||
</label>
|
||||
{reminderError && <p className="text-sm text-[var(--r-danger,#b42318)]">{reminderError}</p>}
|
||||
{reminderSaved && <p className="text-sm text-[var(--r-accent)]">Saved.</p>}
|
||||
<button
|
||||
type="submit"
|
||||
disabled={reminderBusy}
|
||||
className="rounded-full bg-[var(--r-accent)] px-5 py-2 text-sm font-medium text-[var(--r-on)] transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
{reminderBusy ? 'Saving…' : 'Save'}
|
||||
</button>
|
||||
{reminderTest.message && (
|
||||
<p role="status" className={`text-sm ${reminderTest.ok ? 'text-[var(--r-accent)]' : 'text-[var(--r-danger,#b42318)]'}`}>{reminderTest.message}</p>
|
||||
)}
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={reminderBusy}
|
||||
className="rounded-full bg-[var(--r-accent)] px-5 py-2 text-sm font-medium text-[var(--r-on)] transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
{reminderBusy ? 'Saving…' : 'Save'}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={testReminder}
|
||||
disabled={reminderTest.busy || !reminderForm.ntfyTopic.trim()}
|
||||
className="rounded-full border border-[var(--r-line)] px-5 py-2 text-sm font-medium transition hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
{reminderTest.busy ? 'Sending…' : 'Send test notification'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in new issue
Block a user