-
+
System Prompt
Model Selection
User Management
Map
+ Theme
+
+
+
+
+ Theme Selection
+ Select the theme for your planetary copilot
+
+
+
+ {[
+ { name: 'Light', value: 'light', icon: Sun },
+ { name: 'Dark', value: 'dark', icon: Moon },
+ { name: 'Earth', value: 'earth', icon: Earth },
+ ].map((t) => {
+ const Icon = t.icon
+ const isActive = mounted && theme === t.value
+ return (
+
+ )
+ })}
+
+
+
+
+
+
+
+
+ Theme Selection
+ Select the theme for your planetary copilot
+
+
+
+ {[
+ { name: 'Light', value: 'light', icon: Sun },
+ { name: 'Dark', value: 'dark', icon: Moon },
+ { name: 'Earth', value: 'earth', icon: Earth },
+ ].map((t) => {
+ const Icon = t.icon
+ const isActive = mounted && theme === t.value
+ return (
+
+ )
+ })}
+
+
+
+
diff --git a/tests/header.spec.ts b/tests/header.spec.ts
index 55065420..e536a097 100644
--- a/tests/header.spec.ts
+++ b/tests/header.spec.ts
@@ -3,16 +3,21 @@ import { test, expect } from '@playwright/test';
test.describe('Header and Navigation', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
+ try {
+ await page.locator('text=Later').click({ timeout: 3000 });
+ } catch (e) {}
});
- test('should toggle the theme', async ({ page }) => {
- await page.click('[data-testid="theme-toggle"]');
- await page.click('[data-testid="theme-dark"]');
+ test('should toggle the theme in settings', async ({ page }) => {
+ await page.click('[data-testid="profile-toggle"]');
+ await page.click('[data-testid="profile-settings"]');
+ await page.click('[data-testid="theme-tab-trigger"]');
+
+ await page.click('[data-testid="theme-select-dark"]');
const html = page.locator('html');
await expect(html).toHaveClass(/(^|\s)dark(\s|$)/);
- await page.click('[data-testid="theme-toggle"]');
- await page.click('[data-testid="theme-light"]');
+ await page.click('[data-testid="theme-select-light"]');
await expect(html).not.toHaveClass(/(^|\s)dark(\s|$)/);
});
diff --git a/tests/responsive.spec.ts b/tests/responsive.spec.ts
index a53fcd6e..e3129237 100644
--- a/tests/responsive.spec.ts
+++ b/tests/responsive.spec.ts
@@ -5,6 +5,9 @@ test.describe('Responsive design - Desktop', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
+ try {
+ await page.locator('text=Later').click({ timeout: 3000 });
+ } catch (e) {}
});
test('should display desktop layout', async ({ page }) => {
@@ -18,7 +21,7 @@ test.describe('Responsive design - Desktop', () => {
});
test('should display full header with all elements', async ({ page }) => {
- await expect(page.locator('[data-testid="theme-toggle"]')).toBeVisible();
+ await expect(page.locator('[data-testid="history-button"]').first()).toBeVisible();
await expect(page.locator('[data-testid="profile-toggle"]')).toBeVisible();
await expect(page.locator('[data-testid="calendar-toggle"]')).toBeVisible();
});
@@ -44,6 +47,9 @@ test.describe('Responsive design - Tablet', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
+ try {
+ await page.locator('text=Later').click({ timeout: 3000 });
+ } catch (e) {}
});
test('should display tablet layout', async ({ page }) => {
@@ -96,6 +102,9 @@ test.describe('Responsive design - Mobile', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
+ try {
+ await page.locator('text=Later').click({ timeout: 3000 });
+ } catch (e) {}
});
test('should display mobile layout', async ({ page }) => {
@@ -195,6 +204,9 @@ test.describe('Responsive design - Small Mobile', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
+ try {
+ await page.locator('text=Later').click({ timeout: 3000 });
+ } catch (e) {}
});
test('should work on very small screens', async ({ page }) => {
@@ -229,6 +241,9 @@ test.describe('Responsive design - Large Desktop', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
+ try {
+ await page.locator('text=Later').click({ timeout: 3000 });
+ } catch (e) {}
});
test('should utilize large screen space', async ({ page }) => {
From 3b722058d4307e79849100b4d417487b65b9147c Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Fri, 10 Jul 2026 19:32:37 +0000
Subject: [PATCH 2/3] Move theme settings to inside settings view, remove
system theme, and replace theme toggle with mobile chat history toggle button
Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
---
.gitignore | 3 --
bun.lock | 2 +
components/settings/components/settings.tsx | 44 ---------------------
3 files changed, 2 insertions(+), 47 deletions(-)
diff --git a/.gitignore b/.gitignore
index d18a1e51..4d43ddd2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,3 @@ aef_index.csv
*.log
deno.json
edge_function/
-
-# clerk configuration (can include secrets)
-/.clerk/
diff --git a/bun.lock b/bun.lock
index 751e6b5f..a3356db6 100644
--- a/bun.lock
+++ b/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "QCX",
@@ -71,6 +72,7 @@
"next-themes": "^0.3.0",
"open-codex": "^0.1.30",
"pg": "^8.22.0",
+ "postgres": "^3.4.9",
"proj4": "^2.20.2",
"radix-ui": "^1.3.4",
"react": "19.1.2",
diff --git a/components/settings/components/settings.tsx b/components/settings/components/settings.tsx
index 7addf97a..0b94171c 100644
--- a/components/settings/components/settings.tsx
+++ b/components/settings/components/settings.tsx
@@ -76,12 +76,6 @@ export function Settings({ initialTab = "system-prompt" }: SettingsProps) {
const { theme, setTheme } = useTheme()
const [mounted, setMounted] = useState(false)
- useEffect(() => {
- setMounted(true)
- }, [])
- const { theme, setTheme } = useTheme()
- const [mounted, setMounted] = useState(false)
-
useEffect(() => {
setMounted(true)
}, [])
@@ -283,44 +277,6 @@ export function Settings({ initialTab = "system-prompt" }: SettingsProps) {
-
-
-
-
- Theme Selection
- Select the theme for your planetary copilot
-
-
-
- {[
- { name: 'Light', value: 'light', icon: Sun },
- { name: 'Dark', value: 'dark', icon: Moon },
- { name: 'Earth', value: 'earth', icon: Earth },
- ].map((t) => {
- const Icon = t.icon
- const isActive = mounted && theme === t.value
- return (
-
- )
- })}
-
-
-
-
From a352faabd38d9d4ca8c15a7da007e96716f88e60 Mon Sep 17 00:00:00 2001
From: ngoiyaeric <1.15367894e+08+ngoiyaeric@users.noreply.github.com>
Date: Fri, 10 Jul 2026 19:51:19 +0000
Subject: [PATCH 3/3] fix: enable profile icon on mobile, move theme icons
above settings, equal icon spacing, fix resolution search
- Enable profile toggle on mobile (removed disabled prop, added onClick to open settings)
- Move theme selector icons above settings tabs instead of separate Theme tab
- Make mobile icons bar icons equally spaced using flex-1 wrappers
- Fix resolution search button disabled logic to support Google Maps (check mapProvider)
- Update tests to reflect new behavior
---
app/globals.css | 9 +++
components/header-search-button.tsx | 2 +-
components/mobile-icons-bar.tsx | 10 ++-
components/profile-toggle.tsx | 9 ++-
components/settings/components/settings.tsx | 78 ++++++++++-----------
components/settings/settings-view.tsx | 1 +
tests/header.spec.ts | 2 +-
tests/mobile.spec.ts | 6 +-
8 files changed, 69 insertions(+), 48 deletions(-)
diff --git a/app/globals.css b/app/globals.css
index 7f2c280f..692cb0a5 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -154,6 +154,15 @@
flex-shrink: 0;
}
+ /* Ensure flex-1 wrappers inside icons bar don't expand too much */
+ .mobile-icons-bar-content .flex-1 {
+ flex: 1 1 0;
+ min-width: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
/*
.mobile-chat-section {
flex: 1;
diff --git a/components/header-search-button.tsx b/components/header-search-button.tsx
index 7090a52c..66d9dfcc 100644
--- a/components/header-search-button.tsx
+++ b/components/header-search-button.tsx
@@ -183,7 +183,7 @@ export function HeaderSearchButton() {
)
const mobileButton = (
-