@knotpad/app 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -0
- package/app/(app)/calendar/page.tsx +57 -0
- package/app/(app)/error.tsx +35 -0
- package/app/(app)/graph/page.tsx +32 -0
- package/app/(app)/guide/page.tsx +21 -0
- package/app/(app)/kanban/loading.tsx +24 -0
- package/app/(app)/kanban/page.tsx +59 -0
- package/app/(app)/layout.tsx +122 -0
- package/app/(app)/list/loading.tsx +21 -0
- package/app/(app)/list/page.tsx +137 -0
- package/app/(app)/loading.tsx +18 -0
- package/app/(app)/notes/[noteId]/page.tsx +84 -0
- package/app/(app)/notes/layout.tsx +30 -0
- package/app/(app)/notes/page.tsx +39 -0
- package/app/(app)/page.tsx +5 -0
- package/app/(app)/settings/agent-token/page.tsx +59 -0
- package/app/(app)/settings/backup/page.tsx +49 -0
- package/app/(app)/settings/billing/page.tsx +53 -0
- package/app/(app)/settings/calendar/page.tsx +41 -0
- package/app/(app)/settings/layout.test.tsx +39 -0
- package/app/(app)/settings/layout.tsx +71 -0
- package/app/(app)/settings/page.tsx +4 -0
- package/app/(app)/settings/security/page.tsx +43 -0
- package/app/(app)/settings/team/page.tsx +74 -0
- package/app/(app)/settings/workspace/page.tsx +27 -0
- package/app/(app)/tasks/[taskId]/page.tsx +79 -0
- package/app/(auth)/forgot-password/page.tsx +106 -0
- package/app/(auth)/guest/page.tsx +56 -0
- package/app/(auth)/layout.tsx +13 -0
- package/app/(auth)/login/page.tsx +14 -0
- package/app/(auth)/register/page.tsx +193 -0
- package/app/(auth)/reset-password/page.tsx +138 -0
- package/app/api/account/claim/route.tsx +135 -0
- package/app/api/admin/backfill-encryption/route.tsx +43 -0
- package/app/api/admin/license/route.tsx +42 -0
- package/app/api/auth/2fa/route.tsx +148 -0
- package/app/api/auth/[...nextauth]/route.tsx +3 -0
- package/app/api/auth/change-password/route.tsx +61 -0
- package/app/api/auth/check-2fa/route.tsx +19 -0
- package/app/api/auth/forgot-password/route.tsx +65 -0
- package/app/api/auth/reset-password/route.tsx +52 -0
- package/app/api/auth/verify-2fa/route.tsx +88 -0
- package/app/api/backup/download/db/route.ts +29 -0
- package/app/api/backup/download/notes/route.ts +25 -0
- package/app/api/backup/settings/route.ts +92 -0
- package/app/api/billing/checkout/route.tsx +81 -0
- package/app/api/billing/migrate/route.tsx +163 -0
- package/app/api/billing/portal/route.tsx +24 -0
- package/app/api/billing/setup-intent/route.tsx +55 -0
- package/app/api/billing/status/route.tsx +36 -0
- package/app/api/billing/subscribe/route.tsx +85 -0
- package/app/api/billing/webhook/route.tsx +199 -0
- package/app/api/calendar-feeds/[feedId]/route.tsx +67 -0
- package/app/api/calendar-feeds/[feedId]/sync/route.tsx +37 -0
- package/app/api/calendar-feeds/events/route.tsx +82 -0
- package/app/api/calendar-feeds/route.tsx +52 -0
- package/app/api/calendar-feeds/sync-all/route.tsx +34 -0
- package/app/api/cron/calendar-feeds/route.tsx +31 -0
- package/app/api/cron/stale-tasks/route.tsx +51 -0
- package/app/api/cron/sync/route.tsx +34 -0
- package/app/api/devices/[deviceId]/route.tsx +25 -0
- package/app/api/devices/route.tsx +41 -0
- package/app/api/export/route.tsx +40 -0
- package/app/api/feedback/route.tsx +54 -0
- package/app/api/folders/[folderId]/route.tsx +51 -0
- package/app/api/folders/route.tsx +37 -0
- package/app/api/graph/route.tsx +242 -0
- package/app/api/guest/route.tsx +58 -0
- package/app/api/health/route.tsx +10 -0
- package/app/api/holidays/countries/route.tsx +14 -0
- package/app/api/holidays/route.tsx +49 -0
- package/app/api/holidays/states/route.tsx +21 -0
- package/app/api/invites/[token]/route.tsx +131 -0
- package/app/api/invites/route.tsx +74 -0
- package/app/api/mcp/generate-token/route.tsx +55 -0
- package/app/api/mcp/revoke-token/[tokenId]/route.tsx +30 -0
- package/app/api/mcp/update-alias/[tokenId]/route.tsx +22 -0
- package/app/api/notes/[noteId]/export/route.tsx +45 -0
- package/app/api/notes/[noteId]/route.tsx +360 -0
- package/app/api/notes/route.tsx +112 -0
- package/app/api/notifications/route.tsx +44 -0
- package/app/api/register/route.tsx +67 -0
- package/app/api/restore/route.tsx +148 -0
- package/app/api/sync/conflicts/[conflictId]/route.tsx +134 -0
- package/app/api/sync/conflicts/route.tsx +48 -0
- package/app/api/sync/status/route.tsx +49 -0
- package/app/api/sync/trigger/route.tsx +15 -0
- package/app/api/tasks/[taskId]/detail/route.tsx +68 -0
- package/app/api/tasks/[taskId]/route.tsx +259 -0
- package/app/api/tasks/bulk/route.tsx +133 -0
- package/app/api/tasks/route.tsx +36 -0
- package/app/api/workspace/active/route.tsx +39 -0
- package/app/api/workspace/create-team/route.tsx +42 -0
- package/app/api/workspace/kanban-statuses/route.tsx +71 -0
- package/app/api/workspace/members/[memberId]/route.tsx +69 -0
- package/app/api/workspace/route.tsx +24 -0
- package/app/download/page.tsx +170 -0
- package/app/favicon.ico +0 -0
- package/app/generated/prisma/client.d.ts +1 -0
- package/app/generated/prisma/client.js +5 -0
- package/app/generated/prisma/default.d.ts +1 -0
- package/app/generated/prisma/default.js +5 -0
- package/app/generated/prisma/edge.d.ts +1 -0
- package/app/generated/prisma/edge.js +497 -0
- package/app/generated/prisma/index-browser.js +523 -0
- package/app/generated/prisma/index.d.ts +46376 -0
- package/app/generated/prisma/index.js +497 -0
- package/app/generated/prisma/package.json +144 -0
- package/app/generated/prisma/query_compiler_fast_bg.js +2 -0
- package/app/generated/prisma/query_compiler_fast_bg.wasm +0 -0
- package/app/generated/prisma/query_compiler_fast_bg.wasm-base64.js +2 -0
- package/app/generated/prisma/runtime/client.d.ts +3386 -0
- package/app/generated/prisma/runtime/client.js +86 -0
- package/app/generated/prisma/runtime/index-browser.d.ts +90 -0
- package/app/generated/prisma/runtime/index-browser.js +6 -0
- package/app/generated/prisma/runtime/wasm-compiler-edge.js +76 -0
- package/app/generated/prisma/schema.prisma +456 -0
- package/app/generated/prisma/wasm-edge-light-loader.mjs +5 -0
- package/app/generated/prisma/wasm-worker-loader.mjs +5 -0
- package/app/globals.css +54 -0
- package/app/invite/[token]/page.tsx +52 -0
- package/app/layout.tsx +90 -0
- package/app/mcp/route.tsx +430 -0
- package/app/opengraph-image.tsx +120 -0
- package/app/page.tsx +398 -0
- package/app/privacy/page.tsx +69 -0
- package/app/robots.tsx +25 -0
- package/app/sitemap.tsx +36 -0
- package/app/terms/page.tsx +69 -0
- package/app/upgrade/page.tsx +75 -0
- package/auth.config.ts +33 -0
- package/auth.ts +79 -0
- package/bin/brief.js +224 -0
- package/components/auth/login-form.tsx +302 -0
- package/components/auth/password-checklist.tsx +31 -0
- package/components/auth/password-input.tsx +36 -0
- package/components/auth/switch-account-button.test.tsx +22 -0
- package/components/auth/switch-account-button.tsx +19 -0
- package/components/auth/two-factor-input.tsx +116 -0
- package/components/billing/billing-dashboard.tsx +265 -0
- package/components/billing/card-form.tsx +210 -0
- package/components/billing/claim-account-form.tsx +99 -0
- package/components/branding/app-logo.test.tsx +20 -0
- package/components/branding/app-logo.tsx +25 -0
- package/components/calendar/calendar-agenda.tsx +150 -0
- package/components/calendar/calendar-drag.test.tsx +177 -0
- package/components/calendar/calendar-grid.tsx +357 -0
- package/components/calendar/calendar-hooks.test.tsx +27 -0
- package/components/calendar/calendar-hooks.ts +351 -0
- package/components/calendar/calendar-toolbar.test.tsx +68 -0
- package/components/calendar/calendar-toolbar.tsx +291 -0
- package/components/calendar/calendar-types.ts +148 -0
- package/components/calendar/calendar-view.test.tsx +295 -0
- package/components/calendar/calendar-view.tsx +307 -0
- package/components/calendar/day-detail-popover.tsx +174 -0
- package/components/calendar/task-chip.tsx +86 -0
- package/components/command/command-palette.test.tsx +33 -0
- package/components/command/command-palette.tsx +310 -0
- package/components/download-cta.tsx +87 -0
- package/components/feedback/feedback-popup.tsx +207 -0
- package/components/graph/graph-draw.ts +337 -0
- package/components/graph/graph-overlays.tsx +160 -0
- package/components/graph/graph-page.test.tsx +131 -0
- package/components/graph/graph-page.tsx +263 -0
- package/components/graph/graph-types.ts +47 -0
- package/components/graph/graph-view.tsx +322 -0
- package/components/guide/guide-view.tsx +522 -0
- package/components/kanban/kanban-board.test.tsx +128 -0
- package/components/kanban/kanban-board.tsx +361 -0
- package/components/kanban/kanban-card-menu.tsx +102 -0
- package/components/kanban/kanban-card.tsx +227 -0
- package/components/kanban/kanban-column.tsx +49 -0
- package/components/kanban/kanban-status-context.tsx +28 -0
- package/components/landing/calendar-sandbox.test.tsx +15 -0
- package/components/landing/calendar-sandbox.tsx +107 -0
- package/components/landing/graph-sandbox.test.tsx +27 -0
- package/components/landing/graph-sandbox.tsx +80 -0
- package/components/landing/kanban-sandbox.test.tsx +24 -0
- package/components/landing/kanban-sandbox.tsx +101 -0
- package/components/landing/landing-showcase.test.tsx +21 -0
- package/components/landing/landing-showcase.tsx +54 -0
- package/components/landing/list-sandbox.tsx +86 -0
- package/components/landing/mock-workspace.ts +168 -0
- package/components/landing/notes-sandbox.test.tsx +14 -0
- package/components/landing/notes-sandbox.tsx +88 -0
- package/components/layout/app-shell.tsx +83 -0
- package/components/layout/backup-scheduler.tsx +122 -0
- package/components/layout/bottom-nav.tsx +43 -0
- package/components/layout/icon-bar.test.tsx +29 -0
- package/components/layout/icon-bar.tsx +118 -0
- package/components/layout/mobile-top-bar.tsx +68 -0
- package/components/layout/notes-panel-folder.tsx +127 -0
- package/components/layout/notes-panel-note-item.tsx +140 -0
- package/components/layout/notes-panel-task-tab.tsx +63 -0
- package/components/layout/notes-panel-types.ts +44 -0
- package/components/layout/notes-panel.tsx +476 -0
- package/components/layout/notification-bell.tsx +251 -0
- package/components/layout/paywall-screen.tsx +41 -0
- package/components/layout/pro-banner.tsx +76 -0
- package/components/layout/sw-register.tsx +27 -0
- package/components/layout/workspace-switcher.tsx +90 -0
- package/components/notes/mobile-bottom-sheet.tsx +99 -0
- package/components/notes/note-editor-context-menu.tsx +47 -0
- package/components/notes/note-editor-dom.ts +33 -0
- package/components/notes/note-editor-dropdowns.tsx +484 -0
- package/components/notes/note-editor-hooks.ts +692 -0
- package/components/notes/note-editor-keyboard.ts +305 -0
- package/components/notes/note-editor-overlay.tsx +90 -0
- package/components/notes/note-editor.test.tsx +372 -0
- package/components/notes/note-editor.tsx +662 -0
- package/components/notes/note-preview-pane.tsx +156 -0
- package/components/notes/note-tabs.tsx +120 -0
- package/components/notes/note-types.tsx +157 -0
- package/components/settings/accept-invite.tsx +108 -0
- package/components/settings/agent-token-settings.tsx +369 -0
- package/components/settings/backup-restore-settings.test.tsx +25 -0
- package/components/settings/backup-restore-settings.tsx +327 -0
- package/components/settings/calendar-feeds-settings.tsx +489 -0
- package/components/settings/calendar-general-settings.tsx +174 -0
- package/components/settings/confirm-danger-action.test.tsx +215 -0
- package/components/settings/confirm-danger-action.tsx +65 -0
- package/components/settings/security-settings.tsx +252 -0
- package/components/settings/settings-guidance.test.tsx +98 -0
- package/components/settings/team-settings.tsx +319 -0
- package/components/settings/two-factor-auth.tsx +296 -0
- package/components/settings/workspace-settings-client.tsx +363 -0
- package/components/settings/workspace-settings-form.tsx +73 -0
- package/components/sync/conflict-viewer.tsx +247 -0
- package/components/sync/sync-indicator.tsx +171 -0
- package/components/tasks/snippet-thread.tsx +119 -0
- package/components/tasks/status-dot.tsx +47 -0
- package/components/tasks/task-badge.tsx +43 -0
- package/components/tasks/task-detail.test.tsx +187 -0
- package/components/tasks/task-detail.tsx +458 -0
- package/components/tasks/task-list-filters.test.tsx +75 -0
- package/components/tasks/task-list-filters.tsx +163 -0
- package/components/tasks/task-list-types.ts +20 -0
- package/components/tasks/task-list.test.tsx +175 -0
- package/components/tasks/task-list.tsx +481 -0
- package/components/tasks/task-row.tsx +85 -0
- package/components/tasks/task-table-row.tsx +259 -0
- package/components/ui/skeleton.tsx +3 -0
- package/components/ui/toast.test.tsx +42 -0
- package/components/ui/toast.tsx +70 -0
- package/electron/main.ts +251 -0
- package/electron/preload.ts +56 -0
- package/instrumentation.tsx +23 -0
- package/lib/api-error.ts +50 -0
- package/lib/backup/backup-runner.test.ts +32 -0
- package/lib/backup/backup-runner.ts +19 -0
- package/lib/backup/backup-schedule.test.ts +23 -0
- package/lib/backup/backup-schedule.ts +55 -0
- package/lib/backup/backup-settings.test.ts +30 -0
- package/lib/backup/backup-settings.ts +27 -0
- package/lib/backup/export-notes-zip.test.ts +26 -0
- package/lib/backup/export-notes-zip.ts +82 -0
- package/lib/backup/export-workspace-backup.test.ts +17 -0
- package/lib/backup/export-workspace-backup.ts +77 -0
- package/lib/backup/restore-workspace-from-export.test.ts +18 -0
- package/lib/backup/restore-workspace-from-export.ts +183 -0
- package/lib/backup/types.ts +14 -0
- package/lib/brand-icons.ts +1 -0
- package/lib/calendar-feed-crypto.ts +38 -0
- package/lib/calendar-feed.ts +239 -0
- package/lib/client/online-status.ts +47 -0
- package/lib/conflict-resolver.test.ts +57 -0
- package/lib/conflict-resolver.ts +240 -0
- package/lib/db-init.ts +79 -0
- package/lib/email.ts +159 -0
- package/lib/encryption.test.ts +41 -0
- package/lib/encryption.ts +98 -0
- package/lib/extract-snippet.test.ts +123 -0
- package/lib/extract-snippet.ts +69 -0
- package/lib/kanban-status.ts +55 -0
- package/lib/license.ts +21 -0
- package/lib/limits.ts +31 -0
- package/lib/mcp-auth.test.ts +58 -0
- package/lib/mcp-auth.ts +65 -0
- package/lib/mcp-contract.test.ts +25 -0
- package/lib/mcp-contract.ts +210 -0
- package/lib/mcp-handler.ts +31 -0
- package/lib/mcp-url.test.ts +12 -0
- package/lib/mcp-url.ts +7 -0
- package/lib/mentions.test.ts +45 -0
- package/lib/mentions.ts +73 -0
- package/lib/note-crypto.ts +108 -0
- package/lib/note-sync.ts +201 -0
- package/lib/note-title.ts +93 -0
- package/lib/prisma.ts +193 -0
- package/lib/pro-flush.ts +292 -0
- package/lib/rate-limit.ts +57 -0
- package/lib/stripe.ts +38 -0
- package/lib/sync-worker.ts +388 -0
- package/lib/task-parser.test.ts +91 -0
- package/lib/task-parser.ts +81 -0
- package/lib/task-utils.ts +52 -0
- package/lib/use-is-electron.ts +19 -0
- package/lib/use-is-mobile.ts +22 -0
- package/lib/validation/calendar-feed.ts +31 -0
- package/lib/validation/note.ts +27 -0
- package/lib/validation/task.ts +26 -0
- package/lib/view-preferences.test.ts +54 -0
- package/lib/view-preferences.ts +28 -0
- package/lib/workspace.ts +66 -0
- package/next.config.ts +21 -0
- package/package.json +99 -0
- package/postcss.config.mjs +7 -0
- package/prisma/migrations/20260519021916_init/migration.sql +388 -0
- package/prisma/migrations/20260519061113_drop_sync_password/migration.sql +8 -0
- package/prisma/migrations/20260520065016_add_task_start_date/migration.sql +2 -0
- package/prisma/migrations/20260529010600_remove_encryption_fields/migration.sql +12 -0
- package/prisma/migrations/20260529020000_restore_encryption_salt/migration.sql +3 -0
- package/prisma/migrations/20260529030000_add_folders/migration.sql +17 -0
- package/prisma/migrations/20260605000000_deferred_fixes/migration.sql +31 -0
- package/prisma/migrations/20260605020806_add_pending_sync_to_note_and_task/migration.sql +5 -0
- package/prisma/migrations/20260605063634_add_stripe_webhook_event_sync_lock/migration.sql +14 -0
- package/prisma/migrations/20260605100000_add_prod_indexes/migration.sql +26 -0
- package/prisma/migrations/20260608081404_add_kanban_statuses/migration.sql +23 -0
- package/prisma/migrations/20260611032723_add_calendar_feeds/migration.sql +43 -0
- package/prisma/migrations/20260611040000_add_calendar_feed_color/migration.sql +2 -0
- package/prisma/migrations/20260611050000_add_task_priority/migration.sql +14 -0
- package/prisma/migrations/20260612060000_add_critical_priority/migration.sql +2 -0
- package/prisma/migrations/20260613090000_add_backup_settings/migration.sql +25 -0
- package/prisma/migrations/20260614160000_add_feedback/migration.sql +20 -0
- package/prisma/migrations/20260614210000_add_2fa/migration.sql +4 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +457 -0
- package/public/Logo_icon.svg +1 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/icon-192.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/icon.svg +4 -0
- package/public/icon_dark.svg +1 -0
- package/public/knotpad_icon.svg +1 -0
- package/public/knotpad_logo_full.svg +1 -0
- package/public/manifest.json +14 -0
- package/public/next.svg +1 -0
- package/public/sw.js +137 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/tsconfig.json +35 -0
package/app/page.tsx
ADDED
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { auth } from "@/auth";
|
|
2
|
+
import { redirect } from "next/navigation";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { AppLogo } from "@/components/branding/app-logo";
|
|
5
|
+
import DownloadCTA from "@/components/download-cta";
|
|
6
|
+
import { LandingShowcase } from "@/components/landing/landing-showcase";
|
|
7
|
+
|
|
8
|
+
export default async function RootPage() {
|
|
9
|
+
const session = await auth();
|
|
10
|
+
if (session) redirect("/notes");
|
|
11
|
+
|
|
12
|
+
// Local mode (NPX / Electron): skip the marketing landing — go straight
|
|
13
|
+
// to the login page which offers "Start writing" (guest, no account needed).
|
|
14
|
+
if (process.env.IS_CLOUD !== "true") redirect("/login");
|
|
15
|
+
|
|
16
|
+
return <LandingPage />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function LandingPage() {
|
|
20
|
+
const jsonLd = {
|
|
21
|
+
"@context": "https://schema.org",
|
|
22
|
+
"@type": "SoftwareApplication",
|
|
23
|
+
name: "Knotpad",
|
|
24
|
+
description:
|
|
25
|
+
"Note-first project management with AI agent task routing. Write the note — the tasks come with it.",
|
|
26
|
+
url: "https://knotpad.app",
|
|
27
|
+
applicationCategory: "ProductivityApplication",
|
|
28
|
+
operatingSystem: "Windows, macOS, Linux, Web",
|
|
29
|
+
offers: [
|
|
30
|
+
{
|
|
31
|
+
"@type": "Offer",
|
|
32
|
+
name: "Personal Free",
|
|
33
|
+
price: "0",
|
|
34
|
+
priceCurrency: "USD",
|
|
35
|
+
description: "Notes, tasks, Kanban, calendar, graph — fully offline",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"@type": "Offer",
|
|
39
|
+
name: "Personal Pro",
|
|
40
|
+
price: "5",
|
|
41
|
+
priceCurrency: "USD",
|
|
42
|
+
billingPeriod: "month",
|
|
43
|
+
description: "Cloud sync across devices with AES-256 encryption",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"@type": "Offer",
|
|
47
|
+
name: "Team Pro",
|
|
48
|
+
price: "5",
|
|
49
|
+
priceCurrency: "USD",
|
|
50
|
+
billingPeriod: "month per seat",
|
|
51
|
+
description: "Shared team workspace with cloud-only notes",
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
publisher: {
|
|
55
|
+
"@type": "Organization",
|
|
56
|
+
name: "Nexstrive Services",
|
|
57
|
+
url: "https://knotpad.app",
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div className="min-h-screen bg-zinc-950 text-zinc-100">
|
|
63
|
+
<script
|
|
64
|
+
type="application/ld+json"
|
|
65
|
+
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
|
66
|
+
/>
|
|
67
|
+
|
|
68
|
+
{/* Nav */}
|
|
69
|
+
<header className="flex items-center justify-between px-8 py-5 border-b border-zinc-900">
|
|
70
|
+
<div className="flex items-center gap-2">
|
|
71
|
+
<AppLogo className="h-7 w-auto" />
|
|
72
|
+
<span className="rounded-full bg-zinc-800 px-2 py-0.5 text-[10px] text-zinc-400 font-medium lowercase tracking-wider">beta</span>
|
|
73
|
+
</div>
|
|
74
|
+
<div className="flex items-center gap-4">
|
|
75
|
+
<Link href="/login" className="text-sm text-zinc-500 hover:text-zinc-300 transition-colors">
|
|
76
|
+
sign in
|
|
77
|
+
</Link>
|
|
78
|
+
<Link
|
|
79
|
+
href="/register"
|
|
80
|
+
className="rounded-md bg-zinc-100 px-4 py-1.5 text-sm font-medium text-zinc-900 hover:bg-white transition-colors"
|
|
81
|
+
>
|
|
82
|
+
get started free →
|
|
83
|
+
</Link>
|
|
84
|
+
</div>
|
|
85
|
+
</header>
|
|
86
|
+
|
|
87
|
+
<main className="mx-auto max-w-4xl px-8 pt-24 pb-32 space-y-24">
|
|
88
|
+
|
|
89
|
+
{/* Hero */}
|
|
90
|
+
<section>
|
|
91
|
+
<div className="mb-6 inline-flex items-center gap-2 rounded-full border border-zinc-800 bg-zinc-900 px-3 py-1">
|
|
92
|
+
<span className="h-1.5 w-1.5 rounded-full bg-emerald-400" />
|
|
93
|
+
<span className="text-xs text-zinc-400">local-first · no account to start</span>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<h1 className="mb-6 text-5xl font-semibold leading-tight tracking-tight text-zinc-100 sm:text-6xl">
|
|
97
|
+
Write the note.<br />
|
|
98
|
+
<span className="text-zinc-500">The tasks come with it.</span>
|
|
99
|
+
</h1>
|
|
100
|
+
|
|
101
|
+
<p className="mb-10 max-w-xl text-lg text-zinc-400 leading-relaxed">
|
|
102
|
+
Start in a note. Turn checkboxes into real tasks. Assign teammates or AI agents inline,
|
|
103
|
+
then manage the same work in Kanban, Calendar, and Graph without rewriting anything.
|
|
104
|
+
</p>
|
|
105
|
+
|
|
106
|
+
<DownloadCTA />
|
|
107
|
+
|
|
108
|
+
<p className="mt-4 text-xs text-zinc-700">
|
|
109
|
+
Free forever on your machine · $5/mo to sync · $5/seat for teams
|
|
110
|
+
</p>
|
|
111
|
+
</section>
|
|
112
|
+
|
|
113
|
+
{/* Product showcase */}
|
|
114
|
+
<section className="space-y-5">
|
|
115
|
+
<div>
|
|
116
|
+
<h2 className="text-base font-semibold text-zinc-200">One note, four views</h2>
|
|
117
|
+
<p className="mt-1 max-w-2xl text-sm text-zinc-500">
|
|
118
|
+
Write once in the note, then explore the same work in Kanban, List, Calendar, and Graph.
|
|
119
|
+
</p>
|
|
120
|
+
</div>
|
|
121
|
+
<LandingShowcase />
|
|
122
|
+
</section>
|
|
123
|
+
|
|
124
|
+
{/* Four pillars */}
|
|
125
|
+
<section className="grid gap-8 sm:grid-cols-2 lg:grid-cols-4">
|
|
126
|
+
{[
|
|
127
|
+
{
|
|
128
|
+
title: "Notes become tasks",
|
|
129
|
+
body: "Write the plan once. Knotpad turns checkbox lines into tracked work without sending you through a separate task form.",
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
title: "Your team and AI agents share the same source",
|
|
133
|
+
body: "Assign teammates or @agent in the note itself, then keep everyone aligned in one workflow instead of splitting work across tools.",
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
title: "One note, multiple views",
|
|
137
|
+
body: "Switch between Notes, Kanban, Calendar, and Graph without recreating the work or losing the context behind it.",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
title: "Local-first by default",
|
|
141
|
+
body: "Start on your own machine, then add cloud sync only when you need it across devices or across a team.",
|
|
142
|
+
},
|
|
143
|
+
].map((p) => (
|
|
144
|
+
<div key={p.title} className="space-y-2">
|
|
145
|
+
<h3 className="text-sm font-semibold text-zinc-200">{p.title}</h3>
|
|
146
|
+
<p className="text-sm text-zinc-500 leading-relaxed">{p.body}</p>
|
|
147
|
+
</div>
|
|
148
|
+
))}
|
|
149
|
+
</section>
|
|
150
|
+
|
|
151
|
+
{/* MCP Integration */}
|
|
152
|
+
<section className="space-y-5">
|
|
153
|
+
<div>
|
|
154
|
+
<h2 className="text-base font-semibold text-zinc-200">AI agents work alongside your team</h2>
|
|
155
|
+
<p className="mt-1 max-w-2xl text-sm text-zinc-500">
|
|
156
|
+
Knotpad exposes a full MCP (Model Context Protocol) server. Connect Claude Code, Windsurf, Cursor, or any MCP-compatible tool so your AI assistant can read your workspace, claim tasks, and write notes back — all without leaving your terminal.
|
|
157
|
+
</p>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<div className="rounded-xl border border-zinc-800 bg-zinc-900/30 overflow-hidden">
|
|
161
|
+
<div className="grid md:grid-cols-2 divide-y md:divide-y-0 md:divide-x divide-zinc-800">
|
|
162
|
+
<div className="p-6 space-y-4">
|
|
163
|
+
<div className="flex items-center gap-3">
|
|
164
|
+
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-800 border border-zinc-700">
|
|
165
|
+
<span className="text-lg font-bold text-zinc-200">M</span>
|
|
166
|
+
</div>
|
|
167
|
+
<div>
|
|
168
|
+
<h3 className="text-sm font-semibold text-zinc-100">Model Context Protocol</h3>
|
|
169
|
+
<p className="text-xs text-zinc-500">Standard for AI tool integration</p>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<div className="space-y-3">
|
|
174
|
+
<div className="rounded-lg border border-zinc-800 bg-zinc-950 p-3">
|
|
175
|
+
<p className="text-[11px] uppercase tracking-wider text-zinc-600 mb-2">How it works</p>
|
|
176
|
+
<ul className="space-y-1.5 text-xs text-zinc-400">
|
|
177
|
+
<li>Connect your AI tool with a single MCP token</li>
|
|
178
|
+
<li>Your agent reads tasks, notes, and context automatically</li>
|
|
179
|
+
<li>Claim work, update status, and append follow-up notes</li>
|
|
180
|
+
<li>Changes sync bidirectionally — the note stays the source of truth</li>
|
|
181
|
+
</ul>
|
|
182
|
+
</div>
|
|
183
|
+
|
|
184
|
+
<div className="rounded-lg border border-zinc-800 bg-zinc-950 p-3">
|
|
185
|
+
<p className="text-[11px] uppercase tracking-wider text-zinc-600 mb-2">Supported tools</p>
|
|
186
|
+
<div className="flex flex-wrap gap-2">
|
|
187
|
+
{["Claude Code", "Windsurf", "Cursor", "Trae", "Copilot"].map((tool) => (
|
|
188
|
+
<span key={tool} className="rounded-full border border-zinc-700 bg-zinc-900 px-2 py-1 text-[10px] text-zinc-400">
|
|
189
|
+
{tool}
|
|
190
|
+
</span>
|
|
191
|
+
))}
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<div className="p-6 space-y-4">
|
|
198
|
+
<p className="text-[11px] uppercase tracking-wider text-zinc-600">What your agent can do</p>
|
|
199
|
+
<div className="space-y-2 text-xs">
|
|
200
|
+
<div className="rounded-lg border border-zinc-800 bg-zinc-950 p-3">
|
|
201
|
+
<p className="text-zinc-200 font-medium">Pull tasks & plan with notes</p>
|
|
202
|
+
<p className="text-zinc-500 mt-1">Discover open work, read full note context, and understand linked files before starting.</p>
|
|
203
|
+
</div>
|
|
204
|
+
<div className="rounded-lg border border-zinc-800 bg-zinc-950 p-3">
|
|
205
|
+
<p className="text-zinc-200 font-medium">Claim & update status</p>
|
|
206
|
+
<p className="text-zinc-500 mt-1">Reserve tasks to avoid conflicts, then mark in_progress, review, or done as work progresses.</p>
|
|
207
|
+
</div>
|
|
208
|
+
<div className="rounded-lg border border-zinc-800 bg-zinc-950 p-3">
|
|
209
|
+
<p className="text-zinc-200 font-medium">Write & link notes</p>
|
|
210
|
+
<p className="text-zinc-500 mt-1">Create new notes, append follow-up tasks, cross-reference other notes, and auto-parse checkboxes into real tasks.</p>
|
|
211
|
+
</div>
|
|
212
|
+
<div className="rounded-lg border border-zinc-800 bg-zinc-950 p-3">
|
|
213
|
+
<p className="text-zinc-200 font-medium">Stay in sync</p>
|
|
214
|
+
<p className="text-zinc-500 mt-1">Send heartbeats while working long tasks. Released work goes back to the queue with a reason.</p>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
</section>
|
|
221
|
+
|
|
222
|
+
{/* Workspace model */}
|
|
223
|
+
<section className="space-y-5">
|
|
224
|
+
<div>
|
|
225
|
+
<h2 className="text-base font-semibold text-zinc-200">Personal or team. Your call.</h2>
|
|
226
|
+
<p className="text-sm text-zinc-500 mt-1">
|
|
227
|
+
Start alone. Add people when you're ready. Or never — the free version has every view and the full note→task workflow.
|
|
228
|
+
Switch between your personal and team workspaces in one click — your data follows you.
|
|
229
|
+
</p>
|
|
230
|
+
</div>
|
|
231
|
+
<div className="rounded-xl border border-zinc-800 bg-zinc-900/30 divide-y divide-zinc-800">
|
|
232
|
+
{[
|
|
233
|
+
{
|
|
234
|
+
label: "Personal Workspace",
|
|
235
|
+
sub: "Free on your machine · $5/mo if you want cloud sync",
|
|
236
|
+
detail: "Everything stays between you and your devices. Upgrade to sync across machines — your notes are AES-256 encrypted at rest and never stored in plaintext on our servers.",
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
label: "Team Workspace",
|
|
240
|
+
sub: "$5/seat/mo · owner pays, members join free",
|
|
241
|
+
detail: "One person holds the billing. Everyone else just accepts an invite. No awkward “ask your teammate to subscribe” moments.",
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
label: "Cloud-only Notes",
|
|
245
|
+
sub: "Some things shouldn't leave the server.",
|
|
246
|
+
detail: "Toggle any note to cloud-only. It streams to your team while they're in — but never downloads to their machine. When someone leaves the workspace, they lose access immediately. No local copy to walk away with.",
|
|
247
|
+
},
|
|
248
|
+
].map((w) => (
|
|
249
|
+
<div key={w.label} className="p-5 space-y-1">
|
|
250
|
+
<p className="text-sm font-medium text-zinc-200">{w.label}</p>
|
|
251
|
+
<p className="text-xs text-zinc-500">{w.sub}</p>
|
|
252
|
+
<p className="text-sm text-zinc-500 leading-relaxed pt-1">{w.detail}</p>
|
|
253
|
+
</div>
|
|
254
|
+
))}
|
|
255
|
+
</div>
|
|
256
|
+
</section>
|
|
257
|
+
|
|
258
|
+
{/* Pricing */}
|
|
259
|
+
<section className="space-y-5">
|
|
260
|
+
<div>
|
|
261
|
+
<h2 className="text-base font-semibold text-zinc-200">Simple pricing.</h2>
|
|
262
|
+
<p className="text-sm text-zinc-500 mt-1">Free until you need more.</p>
|
|
263
|
+
</div>
|
|
264
|
+
<div className="rounded-xl border border-zinc-800 overflow-hidden">
|
|
265
|
+
<div className="grid sm:grid-cols-3 divide-y sm:divide-y-0 sm:divide-x divide-zinc-800">
|
|
266
|
+
|
|
267
|
+
{/* Personal Free */}
|
|
268
|
+
<div className="p-8 flex flex-col h-full">
|
|
269
|
+
<div className="space-y-5">
|
|
270
|
+
<div>
|
|
271
|
+
<p className="text-xs font-medium uppercase tracking-wider text-zinc-500 mb-1">Personal · Free</p>
|
|
272
|
+
<p className="text-3xl font-semibold text-zinc-100">$0</p>
|
|
273
|
+
<p className="text-xs text-zinc-600 mt-0.5">no card · no account</p>
|
|
274
|
+
</div>
|
|
275
|
+
<ul className="space-y-2 text-sm text-zinc-400">
|
|
276
|
+
{[
|
|
277
|
+
"Notes → tasks, automatically",
|
|
278
|
+
"Kanban, list, calendar, graph",
|
|
279
|
+
"@agent with any MCP tool",
|
|
280
|
+
"Fully offline after setup",
|
|
281
|
+
"Your machine, your data",
|
|
282
|
+
].map((f) => (
|
|
283
|
+
<li key={f} className="flex items-start gap-2">
|
|
284
|
+
<span className="text-emerald-500 mt-0.5">✓</span> {f}
|
|
285
|
+
</li>
|
|
286
|
+
))}
|
|
287
|
+
</ul>
|
|
288
|
+
</div>
|
|
289
|
+
<div className="mt-auto pt-5 space-y-2">
|
|
290
|
+
<Link
|
|
291
|
+
href="/download"
|
|
292
|
+
className="inline-flex items-center justify-center w-full rounded-md border border-zinc-800 bg-zinc-900 px-3 py-2 text-xs font-medium text-zinc-300 hover:bg-zinc-800 transition-colors"
|
|
293
|
+
>
|
|
294
|
+
Download desktop app →
|
|
295
|
+
</Link>
|
|
296
|
+
<div className="rounded-md border border-zinc-800 bg-zinc-900 px-3 py-2 flex justify-center">
|
|
297
|
+
<code className="text-xs font-mono text-zinc-300">npx @knotpad/app</code>
|
|
298
|
+
</div>
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
|
|
302
|
+
{/* Personal Pro */}
|
|
303
|
+
<div className="p-8 flex flex-col h-full bg-zinc-900/40">
|
|
304
|
+
<div className="space-y-5">
|
|
305
|
+
<div>
|
|
306
|
+
<p className="text-xs font-medium uppercase tracking-wider text-zinc-500 mb-1">Personal Pro</p>
|
|
307
|
+
<p className="text-3xl font-semibold text-zinc-100">$5 <span className="text-lg font-normal text-zinc-500">/ mo</span></p>
|
|
308
|
+
<p className="text-xs text-zinc-600 mt-0.5">cancel anytime</p>
|
|
309
|
+
</div>
|
|
310
|
+
<ul className="space-y-2 text-sm text-zinc-400">
|
|
311
|
+
{[
|
|
312
|
+
"Everything in Free",
|
|
313
|
+
"Sync across your devices",
|
|
314
|
+
"AES-256 encrypted at rest",
|
|
315
|
+
"Cloud MCP for AI agents",
|
|
316
|
+
].map((f) => (
|
|
317
|
+
<li key={f} className="flex items-start gap-2">
|
|
318
|
+
<span className="text-blue-400 mt-0.5">✓</span> {f}
|
|
319
|
+
</li>
|
|
320
|
+
))}
|
|
321
|
+
</ul>
|
|
322
|
+
</div>
|
|
323
|
+
<div className="mt-auto pt-5">
|
|
324
|
+
<Link
|
|
325
|
+
href="/register"
|
|
326
|
+
className="inline-flex items-center justify-center w-full rounded-md bg-zinc-100 px-3 py-1.5 text-xs font-semibold text-zinc-900 hover:bg-white transition-colors"
|
|
327
|
+
>
|
|
328
|
+
Get started →
|
|
329
|
+
</Link>
|
|
330
|
+
</div>
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
{/* Team Pro */}
|
|
334
|
+
<div className="p-8 flex flex-col h-full bg-zinc-900/60">
|
|
335
|
+
<div className="space-y-5">
|
|
336
|
+
<div>
|
|
337
|
+
<p className="text-xs font-medium uppercase tracking-wider text-zinc-500 mb-1">Team Pro</p>
|
|
338
|
+
<p className="text-3xl font-semibold text-zinc-100">$5 <span className="text-lg font-normal text-zinc-500">/ seat / mo</span></p>
|
|
339
|
+
<p className="text-xs text-zinc-600 mt-0.5">owner pays for the team</p>
|
|
340
|
+
</div>
|
|
341
|
+
<ul className="space-y-2 text-sm text-zinc-400">
|
|
342
|
+
{[
|
|
343
|
+
"Everything in Personal Pro",
|
|
344
|
+
"Shared team workspace",
|
|
345
|
+
"Owner's personal workspace included",
|
|
346
|
+
"Teammates join free — owner covers their seat",
|
|
347
|
+
"MCP token per person",
|
|
348
|
+
"Cloud-only notes (access revoked on leave)",
|
|
349
|
+
"Add or remove seats anytime",
|
|
350
|
+
].map((f) => (
|
|
351
|
+
<li key={f} className="flex items-start gap-2">
|
|
352
|
+
<span className="text-violet-400 mt-0.5">✓</span> {f}
|
|
353
|
+
</li>
|
|
354
|
+
))}
|
|
355
|
+
</ul>
|
|
356
|
+
</div>
|
|
357
|
+
<div className="mt-auto pt-5">
|
|
358
|
+
<Link
|
|
359
|
+
href="/register"
|
|
360
|
+
className="inline-flex items-center justify-center w-full rounded-md bg-zinc-100 px-3 py-1.5 text-xs font-semibold text-zinc-900 hover:bg-white transition-colors"
|
|
361
|
+
>
|
|
362
|
+
Start with your team →
|
|
363
|
+
</Link>
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
<p className="text-xs text-zinc-600 text-center">
|
|
370
|
+
Every plan has the full feature set. Cloud plans add sync, backup, and collaboration.
|
|
371
|
+
Stripe handles payments — we never store your card.
|
|
372
|
+
</p>
|
|
373
|
+
</section>
|
|
374
|
+
|
|
375
|
+
{/* Footer */}
|
|
376
|
+
<footer className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between text-xs text-zinc-700 border-t border-zinc-900 pt-8">
|
|
377
|
+
<div className="flex flex-col gap-2">
|
|
378
|
+
<div className="flex items-center gap-3">
|
|
379
|
+
<AppLogo className="h-5 w-auto" />
|
|
380
|
+
<span>Knotpad · a product of Nexstrive Services</span>
|
|
381
|
+
</div>
|
|
382
|
+
<p className="text-[11px] text-zinc-800">
|
|
383
|
+
Registration: 202303272747 (TR0292898-P) · Kuala Lumpur, Malaysia
|
|
384
|
+
</p>
|
|
385
|
+
</div>
|
|
386
|
+
<div className="flex items-center gap-4 flex-wrap">
|
|
387
|
+
<Link href="/login" className="hover:text-zinc-500 transition-colors">sign in</Link>
|
|
388
|
+
<Link href="/terms" className="hover:text-zinc-500 transition-colors">terms</Link>
|
|
389
|
+
<Link href="/privacy" className="hover:text-zinc-500 transition-colors">privacy</Link>
|
|
390
|
+
<span className="text-zinc-800">or just run it:</span>
|
|
391
|
+
<code className="font-mono hover:text-zinc-500 transition-colors">npx @knotpad/app</code>
|
|
392
|
+
</div>
|
|
393
|
+
</footer>
|
|
394
|
+
|
|
395
|
+
</main>
|
|
396
|
+
</div>
|
|
397
|
+
);
|
|
398
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import { AppLogo } from "@/components/branding/app-logo";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: "Privacy Policy",
|
|
7
|
+
description:
|
|
8
|
+
"Privacy Policy for Knotpad — how we handle account, workspace, billing, and usage data.",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function PrivacyPage() {
|
|
12
|
+
return (
|
|
13
|
+
<main className="min-h-screen bg-zinc-950 px-6 py-12 text-zinc-100">
|
|
14
|
+
<div className="mx-auto max-w-3xl space-y-10">
|
|
15
|
+
<div className="space-y-4">
|
|
16
|
+
<Link href="/" className="inline-flex">
|
|
17
|
+
<AppLogo className="h-8 w-auto" />
|
|
18
|
+
</Link>
|
|
19
|
+
<div className="space-y-2">
|
|
20
|
+
<h1 className="text-3xl font-semibold tracking-tight">Privacy Policy</h1>
|
|
21
|
+
<p className="text-sm text-zinc-400">
|
|
22
|
+
This policy explains how Knotpad handles account, workspace, billing, and usage data.
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<section className="space-y-3">
|
|
28
|
+
<h2 className="text-lg font-medium text-zinc-200">Information we collect</h2>
|
|
29
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
30
|
+
Knotpad may process account details, workspace membership data, billing records, and the content
|
|
31
|
+
you choose to store or sync through the service.
|
|
32
|
+
</p>
|
|
33
|
+
</section>
|
|
34
|
+
|
|
35
|
+
<section className="space-y-3">
|
|
36
|
+
<h2 className="text-lg font-medium text-zinc-200">How we use information</h2>
|
|
37
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
38
|
+
We use this information to operate the product, authenticate access, support billing, improve
|
|
39
|
+
reliability, and provide customer support.
|
|
40
|
+
</p>
|
|
41
|
+
</section>
|
|
42
|
+
|
|
43
|
+
<section className="space-y-3">
|
|
44
|
+
<h2 className="text-lg font-medium text-zinc-200">Storage and security</h2>
|
|
45
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
46
|
+
Knotpad supports local-first workflows and cloud features. When cloud storage is used, we apply
|
|
47
|
+
the security controls described in the product, including encrypted-at-rest storage where offered.
|
|
48
|
+
</p>
|
|
49
|
+
</section>
|
|
50
|
+
|
|
51
|
+
<section className="space-y-3">
|
|
52
|
+
<h2 className="text-lg font-medium text-zinc-200">Sharing</h2>
|
|
53
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
54
|
+
We do not sell your data. Information may be shared with service providers only as needed to run
|
|
55
|
+
Knotpad features such as authentication, payments, and infrastructure operations.
|
|
56
|
+
</p>
|
|
57
|
+
</section>
|
|
58
|
+
|
|
59
|
+
<section className="space-y-3">
|
|
60
|
+
<h2 className="text-lg font-medium text-zinc-200">Your choices</h2>
|
|
61
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
62
|
+
You can manage your account, workspace membership, and subscription settings inside Knotpad. You
|
|
63
|
+
may also stop using the service and request workspace access changes from the relevant owner.
|
|
64
|
+
</p>
|
|
65
|
+
</section>
|
|
66
|
+
</div>
|
|
67
|
+
</main>
|
|
68
|
+
);
|
|
69
|
+
}
|
package/app/robots.tsx
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MetadataRoute } from "next";
|
|
2
|
+
|
|
3
|
+
export default function robots(): MetadataRoute.Robots {
|
|
4
|
+
return {
|
|
5
|
+
rules: {
|
|
6
|
+
userAgent: "*",
|
|
7
|
+
allow: "/",
|
|
8
|
+
disallow: [
|
|
9
|
+
"/api/",
|
|
10
|
+
"/settings/",
|
|
11
|
+
"/notes/",
|
|
12
|
+
"/calendar/",
|
|
13
|
+
"/kanban/",
|
|
14
|
+
"/list/",
|
|
15
|
+
"/graph/",
|
|
16
|
+
"/tasks/",
|
|
17
|
+
"/upgrade",
|
|
18
|
+
"/invite/",
|
|
19
|
+
"/mcp/",
|
|
20
|
+
"/_next/",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
sitemap: "https://knotpad.app/sitemap.xml",
|
|
24
|
+
};
|
|
25
|
+
}
|
package/app/sitemap.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { MetadataRoute } from "next";
|
|
2
|
+
|
|
3
|
+
export default function sitemap(): MetadataRoute.Sitemap {
|
|
4
|
+
return [
|
|
5
|
+
{
|
|
6
|
+
url: "https://knotpad.app",
|
|
7
|
+
lastModified: new Date(),
|
|
8
|
+
changeFrequency: "weekly",
|
|
9
|
+
priority: 1,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
url: "https://knotpad.app/register",
|
|
13
|
+
lastModified: new Date(),
|
|
14
|
+
changeFrequency: "monthly",
|
|
15
|
+
priority: 0.8,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
url: "https://knotpad.app/login",
|
|
19
|
+
lastModified: new Date(),
|
|
20
|
+
changeFrequency: "monthly",
|
|
21
|
+
priority: 0.5,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
url: "https://knotpad.app/terms",
|
|
25
|
+
lastModified: new Date(),
|
|
26
|
+
changeFrequency: "yearly",
|
|
27
|
+
priority: 0.3,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
url: "https://knotpad.app/privacy",
|
|
31
|
+
lastModified: new Date(),
|
|
32
|
+
changeFrequency: "yearly",
|
|
33
|
+
priority: 0.3,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import { AppLogo } from "@/components/branding/app-logo";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: "Terms of Service",
|
|
7
|
+
description:
|
|
8
|
+
"Terms of Service for Knotpad — note-first project management by Nexstrive Services.",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function TermsPage() {
|
|
12
|
+
return (
|
|
13
|
+
<main className="min-h-screen bg-zinc-950 px-6 py-12 text-zinc-100">
|
|
14
|
+
<div className="mx-auto max-w-3xl space-y-10">
|
|
15
|
+
<div className="space-y-4">
|
|
16
|
+
<Link href="/" className="inline-flex">
|
|
17
|
+
<AppLogo className="h-8 w-auto" />
|
|
18
|
+
</Link>
|
|
19
|
+
<div className="space-y-2">
|
|
20
|
+
<h1 className="text-3xl font-semibold tracking-tight">Terms of Service</h1>
|
|
21
|
+
<p className="text-sm text-zinc-400">
|
|
22
|
+
These terms govern your use of Knotpad and related services provided by Nexstrive.
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<section className="space-y-3">
|
|
28
|
+
<h2 className="text-lg font-medium text-zinc-200">Using Knotpad</h2>
|
|
29
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
30
|
+
You may use Knotpad for personal or business note-taking, task tracking, and collaboration in
|
|
31
|
+
accordance with these terms and all applicable laws.
|
|
32
|
+
</p>
|
|
33
|
+
</section>
|
|
34
|
+
|
|
35
|
+
<section className="space-y-3">
|
|
36
|
+
<h2 className="text-lg font-medium text-zinc-200">Accounts and workspace access</h2>
|
|
37
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
38
|
+
You are responsible for maintaining the security of your account and for activity that occurs
|
|
39
|
+
within your workspaces. Team owners are responsible for managing member access appropriately.
|
|
40
|
+
</p>
|
|
41
|
+
</section>
|
|
42
|
+
|
|
43
|
+
<section className="space-y-3">
|
|
44
|
+
<h2 className="text-lg font-medium text-zinc-200">Billing</h2>
|
|
45
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
46
|
+
Paid Knotpad plans renew according to the billing cycle presented at checkout. You may manage,
|
|
47
|
+
change, or cancel subscriptions through the billing tools made available in the product.
|
|
48
|
+
</p>
|
|
49
|
+
</section>
|
|
50
|
+
|
|
51
|
+
<section className="space-y-3">
|
|
52
|
+
<h2 className="text-lg font-medium text-zinc-200">Acceptable use</h2>
|
|
53
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
54
|
+
You may not use Knotpad to violate the rights of others, distribute malicious software, or
|
|
55
|
+
interfere with the integrity, availability, or security of the service.
|
|
56
|
+
</p>
|
|
57
|
+
</section>
|
|
58
|
+
|
|
59
|
+
<section className="space-y-3">
|
|
60
|
+
<h2 className="text-lg font-medium text-zinc-200">Contact</h2>
|
|
61
|
+
<p className="text-sm leading-7 text-zinc-400">
|
|
62
|
+
For support or legal questions about these terms, contact Nexstrive through the support channel
|
|
63
|
+
associated with your Knotpad workspace or deployment.
|
|
64
|
+
</p>
|
|
65
|
+
</section>
|
|
66
|
+
</div>
|
|
67
|
+
</main>
|
|
68
|
+
);
|
|
69
|
+
}
|