From 026a4d9fac7c794b769e1549a8a840c41c27246c Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Fri, 5 Jun 2026 19:07:14 +0530 Subject: [PATCH] feat(renderer): WelcomeDialog (first-launch quick-start) --- .../components/modals/WelcomeDialog.tsx | 51 +++++++++++++++++++ tests/component/modals/WelcomeDialog.test.tsx | 34 +++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/renderer/components/modals/WelcomeDialog.tsx create mode 100644 tests/component/modals/WelcomeDialog.test.tsx diff --git a/src/renderer/components/modals/WelcomeDialog.tsx b/src/renderer/components/modals/WelcomeDialog.tsx new file mode 100644 index 0000000..04329cc --- /dev/null +++ b/src/renderer/components/modals/WelcomeDialog.tsx @@ -0,0 +1,51 @@ +import { useState } from 'react'; +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; +import { Checkbox } from '@/components/ui/checkbox'; +import { useAppStore } from '@/stores/app-store'; +import { useSettingsStore } from '@/stores/settings-store'; + +export function WelcomeDialog() { + const closeModal = useAppStore((s) => s.closeModal); + const setSetting = useSettingsStore((s) => s.setSetting); + const [dontShow, setDontShow] = useState(false); + + const handleClose = () => { + if (dontShow) setSetting('welcomeDismissed', true); + closeModal(); + }; + + return ( + !o && handleClose()}> + + + Welcome to MarkdownConverter + + A polished editor for Markdown, with PDF, DOCX, and HTML export. + + +
+
+

1. Open a folder

+

File → Open Folder, or ⌘O. Your tree appears on the left.

+
+
+

2. Edit & preview

+

Type on the left, see the rendered preview on the right. Toggle with ⌘\.

+
+
+

3. Export anywhere

+

File → Export to PDF / DOCX / HTML, or batch convert a folder.

+
+
+ + + + +
+
+ ); +} \ No newline at end of file diff --git a/tests/component/modals/WelcomeDialog.test.tsx b/tests/component/modals/WelcomeDialog.test.tsx new file mode 100644 index 0000000..5e84823 --- /dev/null +++ b/tests/component/modals/WelcomeDialog.test.tsx @@ -0,0 +1,34 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { WelcomeDialog } from '@/components/modals/WelcomeDialog'; +import { useSettingsStore } from '@/stores/settings-store'; +import { useAppStore } from '@/stores/app-store'; + +describe('WelcomeDialog', () => { + beforeEach(() => { + localStorage.clear(); + useSettingsStore.setState(useSettingsStore.getInitialState()); + useAppStore.setState({ modal: { kind: null } } as any); + }); + + it('renders a heading and quick-start content', () => { + render(); + expect(screen.getByRole('heading', { name: /welcome/i })).toBeInTheDocument(); + expect(screen.getByText(/open a folder/i)).toBeInTheDocument(); + }); + + it('closing without the checkbox does not dismiss future welcome dialogs', async () => { + render(); + await userEvent.click(screen.getByRole('button', { name: /get started/i })); + expect(useSettingsStore.getState().welcomeDismissed).toBe(false); + expect(useAppStore.getState().modal).toEqual({ kind: null }); + }); + + it('checking "don\'t show again" persists the flag', async () => { + render(); + await userEvent.click(screen.getByRole('checkbox', { name: /don't show again/i })); + await userEvent.click(screen.getByRole('button', { name: /get started/i })); + expect(useSettingsStore.getState().welcomeDismissed).toBe(true); + }); +});