From 51d361d4239ee549d0de632e86aec0a65a2889d9 Mon Sep 17 00:00:00 2001 From: Aayushdev18 Date: Mon, 20 Oct 2025 00:05:11 +0530 Subject: [PATCH 1/2] feat: add basic app layout with navigation - Create Layout component with navigation bar - Add Dashboard, Rules, and Settings page components - Implement client-side routing between pages - Add responsive design with dark mode support - Consolidate all styles in App.css - Maintain existing OpenWithDialog functionality Resolves #3 --- apps/desktop/package-lock.json | 13 -- apps/desktop/src/App.css | 194 +++++++++++++++++++++++++++ apps/desktop/src/App.tsx | 95 +++---------- apps/desktop/src/Layout.tsx | 40 ++++++ apps/desktop/src/pages/Dashboard.tsx | 68 ++++++++++ apps/desktop/src/pages/Rules.tsx | 24 ++++ apps/desktop/src/pages/Settings.tsx | 48 +++++++ 7 files changed, 395 insertions(+), 87 deletions(-) create mode 100644 apps/desktop/src/Layout.tsx create mode 100644 apps/desktop/src/pages/Dashboard.tsx create mode 100644 apps/desktop/src/pages/Rules.tsx create mode 100644 apps/desktop/src/pages/Settings.tsx diff --git a/apps/desktop/package-lock.json b/apps/desktop/package-lock.json index 0f0ab99..8a77ac4 100644 --- a/apps/desktop/package-lock.json +++ b/apps/desktop/package-lock.json @@ -57,7 +57,6 @@ "version": "7.28.4", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -1643,7 +1642,6 @@ "version": "19.2.2", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -1692,7 +1690,6 @@ "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", @@ -1930,7 +1927,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2208,7 +2204,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -2761,7 +2756,6 @@ "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -2822,7 +2816,6 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -4517,7 +4510,6 @@ "version": "4.0.3", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -4578,7 +4570,6 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -4648,7 +4639,6 @@ "node_modules/react": { "version": "19.2.0", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -5353,7 +5343,6 @@ "version": "5.8.3", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5424,7 +5413,6 @@ "version": "7.1.10", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -5633,7 +5621,6 @@ "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/apps/desktop/src/App.css b/apps/desktop/src/App.css index 860c971..65d9cd5 100644 --- a/apps/desktop/src/App.css +++ b/apps/desktop/src/App.css @@ -120,6 +120,200 @@ button { button:active { background-color: #0f0f0f69; } + + /* Layout dark mode */ + .layout { + background-color: #2f2f2f; + } + + .nav { + background-color: #1a1a1a; + border-bottom-color: #333; + } + + .nav-brand h1 { + color: #f6f6f6; + } + + .nav-link { + color: #9aa7b2; + } + + .nav-link:hover { + background-color: #333; + color: #f6f6f6; + } + + .nav-link.active { + background-color: #396cd8; + color: white; + } +} + +/* Layout styles */ +.layout { + display: flex; + flex-direction: column; + height: 100vh; + background-color: #f6f6f6; +} + +/* Navigation styles */ +.nav { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1rem 2rem; + background-color: #ffffff; + border-bottom: 1px solid #e0e0e0; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.nav-brand h1 { + margin: 0; + font-size: 1.5rem; + font-weight: 600; + color: #0f0f0f; +} + +.nav-list { + display: flex; + list-style: none; + margin: 0; + padding: 0; + gap: 1rem; +} + +.nav-item { + margin: 0; +} + +.nav-link { + padding: 0.5rem 1rem; + border: none; + background: transparent; + color: #666; + font-size: 1rem; + font-weight: 500; + cursor: pointer; + border-radius: 6px; + transition: all 0.2s ease; +} + +.nav-link:hover { + background-color: #f0f0f0; + color: #0f0f0f; +} + +.nav-link.active { + background-color: #396cd8; + color: white; +} + +.nav-link.active:hover { + background-color: #2c5aa0; +} + +/* Main content area */ +.main-content { + flex: 1; + padding: 2rem; + overflow-y: auto; +} + +/* Page styles */ +.dashboard, +.rules, +.settings { + max-width: 800px; + margin: 0 auto; +} + +.dashboard h2, +.rules h2, +.settings h2 { + margin-top: 0; + color: #0f0f0f; +} + +.dashboard-section, +.rules-section, +.settings-section { + background: white; + padding: 1.5rem; + margin: 1rem 0; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.dashboard-section h3, +.rules-section h3, +.settings-section h3 { + margin-top: 0; + margin-bottom: 1rem; + color: #333; +} + +.placeholder { + padding: 2rem; + text-align: center; + color: #666; + background: #f8f8f8; + border-radius: 6px; + border: 2px dashed #ddd; +} + +.setting-item { + margin: 1rem 0; +} + +.setting-item label { + display: flex; + align-items: center; + gap: 0.5rem; + font-weight: 500; +} + +.setting-item select { + margin-left: 0.5rem; + padding: 0.25rem 0.5rem; + border: 1px solid #ddd; + border-radius: 4px; + background: white; +} + +/* Dark mode support for pages */ +@media (prefers-color-scheme: dark) { + .dashboard h2, + .rules h2, + .settings h2 { + color: #f6f6f6; + } + + .dashboard-section, + .rules-section, + .settings-section { + background: #1a1a1a; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); + } + + .dashboard-section h3, + .rules-section h3, + .settings-section h3 { + color: #e0e0e0; + } + + .placeholder { + background: #2a2a2a; + color: #9aa7b2; + border-color: #444; + } + + .setting-item select { + background: #2a2a2a; + color: #f6f6f6; + border-color: #444; + } } /* Open With Dialog Styles */ diff --git a/apps/desktop/src/App.tsx b/apps/desktop/src/App.tsx index d10edca..2b68efb 100644 --- a/apps/desktop/src/App.tsx +++ b/apps/desktop/src/App.tsx @@ -1,83 +1,30 @@ import { useState } from 'react'; -import reactLogo from './assets/react.svg'; -import { invoke } from '@tauri-apps/api/core'; import './App.css'; -import OpenWithDialog, { BrowserProfile } from './OpenWithDialog'; +import Layout from './Layout'; +import Dashboard from './pages/Dashboard'; +import Rules from './pages/Rules'; +import Settings from './pages/Settings'; function App() { - const [greetMsg, setGreetMsg] = useState(''); - const [name, setName] = useState(''); - - const [open, setOpen] = useState(false); - const [result, setResult] = useState(null); - - const mockBrowsers: BrowserProfile[] = [ - { id: 'chrome', name: 'Google Chrome', icon: '', profile: 'Personal' }, - { id: 'edge', name: 'Microsoft Edge', icon: '', profile: 'Work' }, - { id: 'firefox', name: 'Firefox', icon: '', profile: null }, - ]; - - async function greet() { - // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ - setGreetMsg(await invoke('greet', { name })); - } - - function handleChoose(b: BrowserProfile, persist: 'just-once' | 'always') { - setOpen(false); - setResult( - `${b.name}${b.profile ? ` (${b.profile})` : ''} — ${ - persist === 'always' ? 'Always' : 'Just once' - }` - ); - } + const [currentPage, setCurrentPage] = useState('dashboard'); + + const renderPage = () => { + switch (currentPage) { + case 'dashboard': + return ; + case 'rules': + return ; + case 'settings': + return ; + default: + return ; + } + }; return ( -
-

Welcome to Tauri + React

- - -

Click on the Tauri, Vite, and React logos to learn more.

- -
{ - e.preventDefault(); - greet(); - }} - > - setName(e.currentTarget.value)} - placeholder='Enter a name...' - /> - -
- -

{greetMsg}

- -
- -
- - {result ?

Last choice: {result}

: null} - - setOpen(false)} - browsers={mockBrowsers} - onChoose={handleChoose} - /> -
+ + {renderPage()} + ); } diff --git a/apps/desktop/src/Layout.tsx b/apps/desktop/src/Layout.tsx new file mode 100644 index 0000000..d346fe3 --- /dev/null +++ b/apps/desktop/src/Layout.tsx @@ -0,0 +1,40 @@ +import { ReactNode } from 'react'; + +type LayoutProps = { + children: ReactNode; + currentPage: string; + onNavigate: (page: string) => void; +}; + +export default function Layout({ children, currentPage, onNavigate }: LayoutProps) { + const navItems = [ + { id: 'dashboard', label: 'Dashboard' }, + { id: 'rules', label: 'Rules' }, + { id: 'settings', label: 'Settings' }, + ]; + + return ( +
+ +
+ {children} +
+
+ ); +} diff --git a/apps/desktop/src/pages/Dashboard.tsx b/apps/desktop/src/pages/Dashboard.tsx new file mode 100644 index 0000000..90d2750 --- /dev/null +++ b/apps/desktop/src/pages/Dashboard.tsx @@ -0,0 +1,68 @@ +import { useState } from 'react'; +import { invoke } from '@tauri-apps/api/core'; +import OpenWithDialog, { BrowserProfile } from '../OpenWithDialog'; + +export default function Dashboard() { + const [greetMsg, setGreetMsg] = useState(''); + const [name, setName] = useState(''); + const [open, setOpen] = useState(false); + const [result, setResult] = useState(null); + + const mockBrowsers: BrowserProfile[] = [ + { id: 'chrome', name: 'Google Chrome', icon: '', profile: 'Personal' }, + { id: 'edge', name: 'Microsoft Edge', icon: '', profile: 'Work' }, + { id: 'firefox', name: 'Firefox', icon: '', profile: null }, + ]; + + async function greet() { + setGreetMsg(await invoke('greet', { name })); + } + + function handleChoose(b: BrowserProfile, persist: 'just-once' | 'always') { + setOpen(false); + setResult( + `${b.name}${b.profile ? ` (${b.profile})` : ''} — ${ + persist === 'always' ? 'Always' : 'Just once' + }` + ); + } + + return ( +
+

Dashboard

+

Welcome to the Open With Browser application. Test the browser selection dialog below.

+ +
+

Test Browser Selection

+
{ + e.preventDefault(); + greet(); + }} + > + setName(e.currentTarget.value)} + placeholder='Enter a name...' + /> + +
+

{greetMsg}

+ +
+ +
+ + {result ?

Last choice: {result}

: null} +
+ + setOpen(false)} + browsers={mockBrowsers} + onChoose={handleChoose} + /> +
+ ); +} diff --git a/apps/desktop/src/pages/Rules.tsx b/apps/desktop/src/pages/Rules.tsx new file mode 100644 index 0000000..c7eef6b --- /dev/null +++ b/apps/desktop/src/pages/Rules.tsx @@ -0,0 +1,24 @@ +export default function Rules() { + return ( +
+

Rules

+

Manage browser selection rules for different domains and file types.

+ +
+

Domain Rules

+

Configure which browser to use for specific domains.

+
+

Domain rules will be displayed here

+
+
+ +
+

File Type Rules

+

Configure which browser to use for specific file types.

+
+

File type rules will be displayed here

+
+
+
+ ); +} diff --git a/apps/desktop/src/pages/Settings.tsx b/apps/desktop/src/pages/Settings.tsx new file mode 100644 index 0000000..3255afc --- /dev/null +++ b/apps/desktop/src/pages/Settings.tsx @@ -0,0 +1,48 @@ +export default function Settings() { + return ( +
+

Settings

+

Configure application preferences and browser settings.

+ +
+

General Settings

+
+ +
+
+ +
+
+ +
+

Browser Settings

+
+ +
+
+ +
+

Advanced

+
+ +
+
+
+ ); +} From 61fc470e3d53ac5e0caa0cd52d52f62e449c9a5c Mon Sep 17 00:00:00 2001 From: Aayushdev18 Date: Mon, 20 Oct 2025 01:00:18 +0530 Subject: [PATCH 2/2] fix: resolve ESLint/Prettier formatting issues - Fix quote style from double quotes to single quotes - Ensure code follows project linting standards - All 31 formatting errors resolved --- apps/desktop/src/Layout.tsx | 22 ++++++++++++---------- apps/desktop/src/pages/Dashboard.tsx | 11 +++++++---- apps/desktop/src/pages/Rules.tsx | 16 +++++++++------- apps/desktop/src/pages/Settings.tsx | 24 ++++++++++++------------ 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/apps/desktop/src/Layout.tsx b/apps/desktop/src/Layout.tsx index d346fe3..e6baaee 100644 --- a/apps/desktop/src/Layout.tsx +++ b/apps/desktop/src/Layout.tsx @@ -6,7 +6,11 @@ type LayoutProps = { onNavigate: (page: string) => void; }; -export default function Layout({ children, currentPage, onNavigate }: LayoutProps) { +export default function Layout({ + children, + currentPage, + onNavigate, +}: LayoutProps) { const navItems = [ { id: 'dashboard', label: 'Dashboard' }, { id: 'rules', label: 'Rules' }, @@ -14,14 +18,14 @@ export default function Layout({ children, currentPage, onNavigate }: LayoutProp ]; return ( -
-