feat: Improve UI layout and navigation

- Increase logo size (48x48 desktop, 56x56 mobile) for better visibility
- Add logo as favicon
- Add logo to mobile header
- Move user menu to navigation bars (sidebar on desktop, bottom bar on mobile)
- Fix desktop chat layout - container structure prevents voice controls cutoff
- Fix mobile bottom bar - use icon-only ActionIcons instead of truncated text buttons
- Hide Create Node/New Conversation buttons on mobile to save header space
- Make fixed header and voice controls work properly with containers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-09 14:43:11 +00:00
parent 0b632a31eb
commit f0284ef813
74 changed files with 6996 additions and 629 deletions

View File

@@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { connectToDB } from '@/lib/db';
import { generateEmbedding } from '@/lib/ai';
import { verifySurrealJwt } from '@/lib/auth/jwt';
/**
* POST /api/suggest-links
@@ -18,6 +19,14 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ error: 'Not authenticated' }, { status: 401 });
}
// Verify JWT to get user's DID
const userSession = verifySurrealJwt(surrealJwt);
if (!userSession) {
return NextResponse.json({ error: 'Invalid auth token' }, { status: 401 });
}
const { did: userDid } = userSession;
const { body } = (await request.json()) as { body: string };
if (!body) {
@@ -28,15 +37,13 @@ export async function POST(request: NextRequest) {
// 1. Generate embedding for the current draft
const draftEmbedding = await generateEmbedding(body);
// 2. Connect to DB (as the user)
// This enforces row-level security - user can only search their own nodes
const db = await connectToDB(surrealJwt);
// 2. Connect to DB with root credentials
const db = await connectToDB();
// 3. Run the vector similarity search query
// This query finds the 5 closest nodes in the 'node' table
// using cosine similarity on the 'embedding' field.
// It only searches nodes WHERE user_did = $token.did,
// which is enforced by the table's PERMISSIONS.
// We filter by user_did to ensure users only see their own nodes.
const query = `
SELECT
id,
@@ -45,6 +52,7 @@ export async function POST(request: NextRequest) {
atp_uri,
vector::similarity::cosine(embedding, $draft_embedding) AS score
FROM node
WHERE user_did = $user_did
ORDER BY score DESC
LIMIT 5;
`;
@@ -57,6 +65,7 @@ export async function POST(request: NextRequest) {
score: number;
}>]>(query, {
draft_embedding: draftEmbedding,
user_did: userDid,
});
// The query returns an array of result sets. We want the first one.