From 89b50637867ee673e668931b84bcb5747b29095d Mon Sep 17 00:00:00 2001
From: Timothy Cardoza
Date: Fri, 27 Feb 2026 14:53:53 -0600
Subject: [PATCH] working api create note, view note, view notes, create task
with ui
---
src/App.tsx | 35 ++++++++++++++++++++++---------
src/views/NotepadView.tsx | 4 +---
test-embed.html | 44 ++++++++++++++++++++++++++++-----------
3 files changed, 58 insertions(+), 25 deletions(-)
diff --git a/src/App.tsx b/src/App.tsx
index ffc3f4d..c15edc4 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,4 +1,4 @@
-import { type Component, createSignal, Show, onMount, onCleanup, lazy, Suspense } from 'solid-js';
+import { type Component, createSignal, onMount, onCleanup, createMemo, lazy, Suspense, Show } from 'solid-js';
import { Layout } from './components/Layout';
import { EmbedLayout } from './components/EmbedLayout';
import { EmbedAuthWrapper } from './components/EmbedAuthWrapper';
@@ -23,8 +23,13 @@ const App: Component = () => {
// Basic routing state
const [currentView, setCurrentView] = createSignal("critical");
const [isAuthenticated, setIsAuthenticated] = createSignal(pb.authStore.isValid);
+ const [location, setLocation] = createSignal(window.location.href);
onMount(() => {
+ const handleLocChange = () => setLocation(window.location.href);
+ window.addEventListener('popstate', handleLocChange);
+ window.addEventListener('hashchange', handleLocChange);
+
const removeListener = pb.authStore.onChange((token) => {
console.log('[DEBUG] pb.authStore.onChange fired, token present:', !!token);
setIsAuthenticated(!!token);
@@ -33,7 +38,11 @@ const App: Component = () => {
}
}, true);
- onCleanup(() => removeListener());
+ onCleanup(() => {
+ removeListener();
+ window.removeEventListener('popstate', handleLocChange);
+ window.removeEventListener('hashchange', handleLocChange);
+ });
// Background preload of other views when idle
const idleCallback = (window as any).requestIdleCallback || ((cb: any) => setTimeout(cb, 1000));
@@ -59,15 +68,19 @@ const App: Component = () => {
// Determine if we are in an embed route (check both path and hash for compatibility)
const isEmbed = () => {
- const path = window.location.pathname;
- const hash = window.location.hash;
+ const loc = location(); // Reactive dependency
+ const url = new URL(loc);
+ const path = url.pathname;
+ const hash = url.hash;
const res = path.startsWith('/embed/') || hash.startsWith('#/embed/');
- console.log('[DEBUG] isEmbed check:', { res, path, hash, href: window.location.href });
+ console.log('[DEBUG] isEmbed check:', { res, path, hash, href: loc });
return res;
};
const getEmbedView = () => {
- const fullPath = window.location.pathname + window.location.hash;
+ const loc = location(); // Reactive dependency
+ const url = new URL(loc);
+ const fullPath = url.pathname + url.hash;
let view = null;
if (fullPath.includes('/notes')) view = 'embed_notes';
else if (fullPath.includes('/quick-add')) view = 'embed_quick_add';
@@ -101,10 +114,12 @@ const App: Component = () => {
}>
{(() => {
- const searchParams = new URLSearchParams(window.location.search);
- const noteIdFromUrl = searchParams.get('noteId');
- const [selectedNoteId, setSelectedNoteId] = createSignal(noteIdFromUrl);
- return ;
+ const noteIdFromUrl = createMemo(() => {
+ const params = new URLSearchParams(new URL(location()).search);
+ return params.get('noteId');
+ });
+ console.log('[DEBUG App] Rendering embed/notes context. noteId trace:', noteIdFromUrl());
+ return { }} hideNavigation={!!noteIdFromUrl()} />;
})()}
diff --git a/src/views/NotepadView.tsx b/src/views/NotepadView.tsx
index d1ca49f..2f7e03e 100644
--- a/src/views/NotepadView.tsx
+++ b/src/views/NotepadView.tsx
@@ -23,9 +23,7 @@ export const NotepadView: Component<{
// Derived states
const activeNote = createMemo(() => {
const id = props.selectedNoteId?.trim();
- const note = store.notes.find(n => n.id === id) || null;
- console.log('[DEBUG NotepadView] store.notes length:', store.notes.length, 'selectedNoteId:', id, 'found Note:', !!note);
- return note;
+ return store.notes.find(n => n.id === id) || null;
});
const handleUpdateNote = async (id: string, data: Partial) => {
diff --git a/test-embed.html b/test-embed.html
index 29146f8..5644486 100644
--- a/test-embed.html
+++ b/test-embed.html
@@ -160,11 +160,12 @@
2. Creating Notes Programmatically (API):
Before embedding, a sister app can create a Note via PocketBase API to retrieve a new
noteId. By default, notes should have an array of tags and a
- title.
+ title.
+
Using the PocketBase JS SDK:
-const record = await pb.collection('notes').create({
+const record = await pb.collection('TasGrid_Notes').create({
title: "Sister App Payload",
content: "<p>Initial content here...</p>",
tags: ["sister_app_export"],
@@ -178,7 +179,7 @@ const newNoteId = record.id;
Using standard REST API (fetch):
-const res = await fetch('https://pocketbase.ccllc.pro/api/collections/notes/records', {
+const res = await fetch('https://pocketbase.ccllc.pro/api/collections/TasGrid_Notes/records', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -197,14 +198,24 @@ const newNoteId = data.id;
3. Authentication Protocol:
The parent application must send a postMessage to the iframe immediately after the
- iframe loads (or whenever auth state changes).
+ iframe loads (or whenever auth state changes). Since iframes reset their internal state on
+ navigation,
+ you should always sync auth on the onload event.
+ Example using vanilla JS:
-iframe.contentWindow.postMessage({
- type: "TASGRID_AUTH",
- token: "YOUR_POCKETBASE_TOKEN",
- user: { /* optional PB user record */ }
-}, "*");
+// 1. Define sync function
+function syncAuth(iframe) {
+ iframe.contentWindow.postMessage({
+ type: "TASGRID_AUTH",
+ token: pb.authStore.token,
+ user: pb.authStore.model
+ }, "*");
+}
+
+// 2. Attach to iframe (either in HTML or via JS)
+// <iframe onload="syncAuth(this)" src="..."></iframe>
+
4. Responsiveness:
Both routes are designed to be fluid. Ensure your iframe container has defined dimensions; the
@@ -221,7 +232,7 @@ iframe.contentWindow.postMessage({
Notes Embed
/embed/notes
-
+
@@ -230,7 +241,8 @@ iframe.contentWindow.postMessage({
Quick Add Embed
/embed/quick-add
-
+
@@ -238,6 +250,14 @@ iframe.contentWindow.postMessage({
const pb = new PocketBase('https://pocketbase.ccllc.pro');
const statusEl = document.getElementById('status');
+ function syncAuthOnLoad(iframe) {
+ console.log(`Iframe ${iframe.id} loaded, checking auth sync...`);
+ if (pb.authStore.isValid) {
+ console.log(`Syncing existing auth to ${iframe.id}`);
+ sendAuthToIframes();
+ }
+ }
+
function loadSpecificNote() {
const id = document.getElementById('note-id-input').value.trim();
const iframe = document.getElementById('notes-iframe');
@@ -261,7 +281,7 @@ iframe.contentWindow.postMessage({
try {
// Using PocketBase SDK to mimic a REST API call from sister app
- const record = await pb.collection('notes').create({
+ const record = await pb.collection('TasGrid_Notes').create({
title: title,
content: "This note was created automatically via the API script!
",
tags: ["api_generated"],