ArunKr commited on
Commit
cc7e11f
·
verified ·
1 Parent(s): 7ac3387

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. static/dashboard.html +66 -3
  2. supabase_user_notes.sql +46 -0
static/dashboard.html CHANGED
@@ -64,9 +64,13 @@
64
 
65
  /* Text utility overrides for light mode */
66
  [data-theme="light"] .text-white { color: var(--app-fg) !important; }
67
- [data-theme="light"] .text-gray-300 { color: rgba(30, 41, 59, 0.9) !important; }
68
- [data-theme="light"] .text-gray-400 { color: rgba(30, 41, 59, 0.72) !important; }
69
- [data-theme="light"] .text-gray-500 { color: rgba(30, 41, 59, 0.6) !important; }
 
 
 
 
70
 
71
  /* Inputs in light mode */
72
  [data-theme="light"] input,
@@ -642,6 +646,23 @@
642
  </div>
643
  <div id="settings-mcp-server-list" class="space-y-3"></div>
644
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
  </div>
646
  </div>
647
 
@@ -1198,6 +1219,7 @@
1198
  }
1199
 
1200
  loadProviders();
 
1201
  await loadChatHistoryList();
1202
  createTerminalTab(); // Init first tab
1203
  applyTerminalLayout();
@@ -2578,6 +2600,47 @@
2578
  }
2579
  }
2580
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2581
  init();
2582
  </script>
2583
  </body>
 
64
 
65
  /* Text utility overrides for light mode */
66
  [data-theme="light"] .text-white { color: var(--app-fg) !important; }
67
+ [data-theme="light"] .text-gray-300 { color: rgba(15, 23, 42, 0.92) !important; }
68
+ [data-theme="light"] .text-gray-400 { color: rgba(15, 23, 42, 0.78) !important; }
69
+ [data-theme="light"] .text-gray-500 { color: rgba(15, 23, 42, 0.66) !important; }
70
+ [data-theme="light"] .text-gray-200 { color: rgba(15, 23, 42, 0.96) !important; }
71
+
72
+ [data-theme="light"] a { color: #1d4ed8; }
73
+ [data-theme="light"] .prose a { color: #1d4ed8; }
74
 
75
  /* Inputs in light mode */
76
  [data-theme="light"] input,
 
646
  </div>
647
  <div id="settings-mcp-server-list" class="space-y-3"></div>
648
  </div>
649
+
650
+ <div class="pt-4 border-t border-gray-700">
651
+ <div class="flex items-center justify-between gap-2 mb-2">
652
+ <div class="font-semibold text-gray-200">Notes</div>
653
+ <button onclick="saveUserNotes()"
654
+ class="bg-green-600 hover:bg-green-700 text-white px-2 py-1 rounded text-xs">Save</button>
655
+ </div>
656
+ <div class="text-xs text-gray-400 mb-2">Personal markdown notes (saved to Supabase).</div>
657
+ <div class="grid grid-cols-1 gap-3">
658
+ <textarea id="notes-editor" rows="8"
659
+ class="w-full bg-gray-700 text-sm rounded border border-gray-600 p-2 text-white outline-none focus:border-blue-500 font-mono"
660
+ placeholder="# Notes..."></textarea>
661
+ <div class="text-xs text-gray-400">Preview</div>
662
+ <div id="notes-preview" class="prose prose-invert max-w-none bg-gray-900/40 border border-gray-700 rounded-lg p-3 overflow-auto"></div>
663
+ <div id="notes-status" class="text-xs text-gray-500"></div>
664
+ </div>
665
+ </div>
666
  </div>
667
  </div>
668
 
 
1219
  }
1220
 
1221
  loadProviders();
1222
+ await initNotes();
1223
  await loadChatHistoryList();
1224
  createTerminalTab(); // Init first tab
1225
  applyTerminalLayout();
 
2600
  }
2601
  }
2602
 
2603
+ async function initNotes() {
2604
+ const editor = document.getElementById('notes-editor');
2605
+ const preview = document.getElementById('notes-preview');
2606
+ const status = document.getElementById('notes-status');
2607
+ if (!editor || !preview) return;
2608
+
2609
+ editor.addEventListener('input', () => {
2610
+ renderMarkdownInto(preview, editor.value || '');
2611
+ if (status) status.textContent = 'Not saved';
2612
+ });
2613
+
2614
+ try {
2615
+ const { data: { user } } = await supabase.auth.getUser();
2616
+ if (!user) return;
2617
+ const { data, error } = await supabase.from('user_notes').select('content,updated_at').eq('user_id', user.id).maybeSingle();
2618
+ if (error) throw error;
2619
+ editor.value = data?.content || '';
2620
+ renderMarkdownInto(preview, editor.value || '');
2621
+ if (status) status.textContent = data?.updated_at ? `Loaded (${new Date(data.updated_at).toLocaleString()})` : 'No notes yet';
2622
+ } catch (e) {
2623
+ if (status) status.textContent = 'Notes table not configured yet.';
2624
+ console.warn('Notes load failed', e);
2625
+ }
2626
+ }
2627
+
2628
+ async function saveUserNotes() {
2629
+ const editor = document.getElementById('notes-editor');
2630
+ const status = document.getElementById('notes-status');
2631
+ if (!editor) return;
2632
+ try {
2633
+ const { data: { user } } = await supabase.auth.getUser();
2634
+ if (!user) return;
2635
+ const content = editor.value || '';
2636
+ const { error } = await supabase.from('user_notes').upsert({ user_id: user.id, content }, { onConflict: 'user_id' });
2637
+ if (error) throw error;
2638
+ if (status) status.textContent = `Saved (${new Date().toLocaleString()})`;
2639
+ } catch (e) {
2640
+ if (status) status.textContent = `Save failed: ${e?.message || e}`;
2641
+ }
2642
+ }
2643
+
2644
  init();
2645
  </script>
2646
  </body>
supabase_user_notes.sql ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -- Simple per-user notes storage (single row per user).
2
+ -- Run this in Supabase SQL Editor.
3
+
4
+ create table if not exists public.user_notes (
5
+ user_id uuid primary key references auth.users (id) on delete cascade,
6
+ content text not null default '',
7
+ updated_at timestamptz not null default now()
8
+ );
9
+
10
+ create or replace function public.set_notes_updated_at()
11
+ returns trigger
12
+ language plpgsql
13
+ as $$
14
+ begin
15
+ new.updated_at = now();
16
+ return new;
17
+ end;
18
+ $$;
19
+
20
+ drop trigger if exists user_notes_set_updated_at on public.user_notes;
21
+ create trigger user_notes_set_updated_at
22
+ before update on public.user_notes
23
+ for each row
24
+ execute procedure public.set_notes_updated_at();
25
+
26
+ alter table public.user_notes enable row level security;
27
+
28
+ drop policy if exists "user_notes_select_own" on public.user_notes;
29
+ create policy "user_notes_select_own"
30
+ on public.user_notes
31
+ for select
32
+ using (auth.uid() = user_id);
33
+
34
+ drop policy if exists "user_notes_insert_own" on public.user_notes;
35
+ create policy "user_notes_insert_own"
36
+ on public.user_notes
37
+ for insert
38
+ with check (auth.uid() = user_id);
39
+
40
+ drop policy if exists "user_notes_update_own" on public.user_notes;
41
+ create policy "user_notes_update_own"
42
+ on public.user_notes
43
+ for update
44
+ using (auth.uid() = user_id)
45
+ with check (auth.uid() = user_id);
46
+