Vijayadhith7 commited on
Commit
dda1e85
·
verified ·
1 Parent(s): d0889c8

build a fullstack website browser with all integrations and api's

Browse files

Build an AI-powered web browser application with the following features:
1. CORE FEATURES
• AI search assistant that summarizes results, answers queries, and opens relevant websites.
• Built-in chatbot sidebar (like ChatGPT) that can analyze the currently opened webpage.
• Voice search + voice response.
• Multi-tab browsing UI.
• History, bookmarks, downloads page.
• Dark mode + light mode.
2. AI FUNCTIONALITY
• Use an LLM model for:
- Searching the web
- Summarizing webpages
- Explaining articles
- Performing tasks like “find cheapest flights”, “extract table data”, etc.
• Provide "Ask this page" button for content analysis.
• Allow user to send a screenshot of the page to the AI.
3. UI REQUIREMENTS
• Modern UI similar to Arc Browser / Opera / Edge.
• Left sidebar:
- Home
- Bookmarks
- History
- Downloads
- Settings
- AI Assistant
• Top address bar with:
- Back / forward
- Reload
- Search bar
- Microphone icon for voice input
• Smooth animations, rounded corners, neumorphic/glassmorphism style.
4. TECH STACK
• Frontend: React + Tailwind CSS
• Backend: Node.js / Express
• AI: OpenAI API or Gemini API
• Browser engine: Use Electron.js to create a desktop app.
5. ADDITIONAL REQUIREMENTS
• Save user data locally using IndexedDB or localStorage.
• Support PDF view, video playback, file downloads.
• Add loading shimmer whenever a page loads.
• Add keyboard shortcuts (Ctrl+T, Ctrl+W, Ctrl+Shift+T, Ctrl+L, etc.)
• Include a settings page for:
- API key input
- Clear cache/history
- Change theme
- Enable/disable AI features
6. OUTPUT EXPECTATION
• Generate full folder structure.
• Generate all React components.
• Generate backend API routes.
• Provide installation steps.
• Provide code in fully working forma

README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Shadowstack Browser
3
- emoji: 👀
4
- colorFrom: indigo
5
  colorTo: yellow
 
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: ShadowStack Browser 🌐
3
+ colorFrom: red
 
4
  colorTo: yellow
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/footer.js ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomFooter extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ .social-icon {
7
+ transition: all 0.3s ease;
8
+ }
9
+ .social-icon:hover {
10
+ transform: translateY(-3px);
11
+ }
12
+ </style>
13
+ <footer class="bg-gray-800 border-t border-gray-700 py-12">
14
+ <div class="container mx-auto px-4">
15
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
16
+ <div class="md:col-span-2">
17
+ <h3 class="text-xl font-bold mb-4 bg-gradient-to-r from-primary-500 to-secondary-500 bg-clip-text text-transparent">ShadowStack Noir</h3>
18
+ <p class="text-gray-400 mb-4">
19
+ Fullstack development solutions for modern businesses. We build scalable, secure, and performant web applications.
20
+ </p>
21
+ <div class="flex space-x-4">
22
+ <a href="#" class="social-icon text-gray-400 hover:text-primary-500">
23
+ <i data-feather="github"></i>
24
+ </a>
25
+ <a href="#" class="social-icon text-gray-400 hover:text-primary-500">
26
+ <i data-feather="twitter"></i>
27
+ </a>
28
+ <a href="#" class="social-icon text-gray-400 hover:text-primary-500">
29
+ <i data-feather="linkedin"></i>
30
+ </a>
31
+ <a href="#" class="social-icon text-gray-400 hover:text-primary-500">
32
+ <i data-feather="instagram"></i>
33
+ </a>
34
+ </div>
35
+ </div>
36
+
37
+ <div>
38
+ <h4 class="text-lg font-semibold mb-4">Quick Links</h4>
39
+ <ul class="space-y-2">
40
+ <li><a href="/" class="text-gray-400 hover:text-white">Home</a></li>
41
+ <li><a href="/services" class="text-gray-400 hover:text-white">Services</a></li>
42
+ <li><a href="/projects" class="text-gray-400 hover:text-white">Projects</a></li>
43
+ <li><a href="/about" class="text-gray-400 hover:text-white">About Us</a></li>
44
+ <li><a href="/contact" class="text-gray-400 hover:text-white">Contact</a></li>
45
+ </ul>
46
+ </div>
47
+
48
+ <div>
49
+ <h4 class="text-lg font-semibold mb-4">Contact</h4>
50
+ <ul class="space-y-2 text-gray-400">
51
+ <li class="flex items-center space-x-2">
52
+ <i data-feather="mail"></i>
53
+ <span>contact@shadowstack.dev</span>
54
+ </li>
55
+ <li class="flex items-center space-x-2">
56
+ <i data-feather="phone"></i>
57
+ <span>+1 (555) 123-4567</span>
58
+ </li>
59
+ <li class="flex items-center space-x-2">
60
+ <i data-feather="map-pin"></i>
61
+ <span>San Francisco, CA</span>
62
+ </li>
63
+ </ul>
64
+ </div>
65
+ </div>
66
+
67
+ <div class="border-t border-gray-700 mt-12 pt-8 text-center text-gray-500">
68
+ <p>&copy; ${new Date().getFullYear()} ShadowStack Noir. All rights reserved.</p>
69
+ </div>
70
+ </div>
71
+ </footer>
72
+ `;
73
+ }
74
+ }
75
+
76
+ customElements.define('custom-footer', CustomFooter);
components/navbar.js ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomNavbar extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ .nav-link {
7
+ position: relative;
8
+ }
9
+ .nav-link::after {
10
+ content: '';
11
+ position: absolute;
12
+ bottom: -2px;
13
+ left: 0;
14
+ width: 0;
15
+ height: 2px;
16
+ background-color: #7c3aed;
17
+ transition: width 0.3s ease;
18
+ }
19
+ .nav-link:hover::after {
20
+ width: 100%;
21
+ }
22
+ </style>
23
+ <nav class="bg-gray-800 border-b border-gray-700">
24
+ <div class="container mx-auto px-4">
25
+ <div class="flex justify-between items-center py-4">
26
+ <a href="/" class="flex items-center space-x-2">
27
+ <span class="text-2xl font-bold bg-gradient-to-r from-primary-500 to-secondary-500 bg-clip-text text-transparent">ShadowStack</span>
28
+ </a>
29
+
30
+ <div class="hidden md:flex items-center space-x-8">
31
+ <a href="/" class="nav-link text-gray-300 hover:text-white">Home</a>
32
+ <a href="/services" class="nav-link text-gray-300 hover:text-white">Services</a>
33
+ <a href="/projects" class="nav-link text-gray-300 hover:text-white">Projects</a>
34
+ <a href="/about" class="nav-link text-gray-300 hover:text-white">About</a>
35
+ <a href="/contact" class="nav-link text-gray-300 hover:text-white">Contact</a>
36
+
37
+ <button id="themeToggle" class="p-2 rounded-full hover:bg-gray-700">
38
+ <i data-feather="moon" class="text-gray-300"></i>
39
+ </button>
40
+ </div>
41
+
42
+ <button class="md:hidden p-2 rounded-full hover:bg-gray-700" id="mobileMenuButton">
43
+ <i data-feather="menu" class="text-gray-300"></i>
44
+ </button>
45
+ </div>
46
+
47
+ <!-- Mobile menu -->
48
+ <div class="md:hidden hidden py-4 border-t border-gray-700" id="mobileMenu">
49
+ <div class="flex flex-col space-y-4">
50
+ <a href="/" class="text-gray-300 hover:text-white">Home</a>
51
+ <a href="/services" class="text-gray-300 hover:text-white">Services</a>
52
+ <a href="/projects" class="text-gray-300 hover:text-white">Projects</a>
53
+ <a href="/about" class="text-gray-300 hover:text-white">About</a>
54
+ <a href="/contact" class="text-gray-300 hover:text-white">Contact</a>
55
+
56
+ <div class="flex justify-between items-center pt-4 border-t border-gray-700">
57
+ <span>Dark Mode</span>
58
+ <button id="mobileThemeToggle" class="p-2 rounded-full hover:bg-gray-700">
59
+ <i data-feather="moon" class="text-gray-300"></i>
60
+ </button>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </nav>
66
+ `;
67
+
68
+ // Add event listeners after rendering
69
+ setTimeout(() => {
70
+ const themeToggle = this.shadowRoot.getElementById('themeToggle');
71
+ const mobileThemeToggle = this.shadowRoot.getElementById('mobileThemeToggle');
72
+ const mobileMenuButton = this.shadowRoot.getElementById('mobileMenuButton');
73
+ const mobileMenu = this.shadowRoot.getElementById('mobileMenu');
74
+
75
+ if (themeToggle) {
76
+ themeToggle.addEventListener('click', this.toggleTheme);
77
+ }
78
+
79
+ if (mobileThemeToggle) {
80
+ mobileThemeToggle.addEventListener('click', this.toggleTheme);
81
+ }
82
+
83
+ if (mobileMenuButton) {
84
+ mobileMenuButton.addEventListener('click', () => {
85
+ mobileMenu.classList.toggle('hidden');
86
+ feather.replace();
87
+ });
88
+ }
89
+ }, 0);
90
+ }
91
+
92
+ toggleTheme() {
93
+ const html = document.documentElement;
94
+ html.classList.toggle('dark');
95
+
96
+ // Save preference to localStorage
97
+ const isDark = html.classList.contains('dark');
98
+ localStorage.setItem('darkMode', isDark);
99
+
100
+ // Update icons
101
+ const icons = this.shadowRoot.querySelectorAll('[data-feather]');
102
+ icons.forEach(icon => {
103
+ if (icon.dataset.feather === 'moon' && !isDark) {
104
+ icon.dataset.feather = 'sun';
105
+ } else if (icon.dataset.feather === 'sun' && isDark) {
106
+ icon.dataset.feather = 'moon';
107
+ }
108
+ });
109
+ feather.replace();
110
+ }
111
+ }
112
+
113
+ customElements.define('custom-navbar', CustomNavbar);
index.html CHANGED
@@ -1,19 +1,93 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ShadowStack Noir | Fullstack Development</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script>
10
+ tailwind.config = {
11
+ darkMode: 'class',
12
+ theme: {
13
+ extend: {
14
+ colors: {
15
+ primary: {
16
+ 500: '#7c3aed',
17
+ 600: '#6d28d9',
18
+ },
19
+ secondary: {
20
+ 500: '#14b8a6',
21
+ 600: '#0d9488',
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ </script>
28
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
29
+ <script src="https://unpkg.com/feather-icons"></script>
30
+ <script src="components/navbar.js"></script>
31
+ <script src="components/footer.js"></script>
32
+ </head>
33
+ <body class="bg-gray-900 text-gray-100 min-h-screen flex flex-col">
34
+ <custom-navbar></custom-navbar>
35
+
36
+ <main class="flex-grow container mx-auto px-4 py-12">
37
+ <section class="hero mb-20">
38
+ <div class="max-w-4xl mx-auto text-center">
39
+ <h1 class="text-5xl md:text-6xl font-bold mb-6 bg-gradient-to-r from-primary-500 to-secondary-500 bg-clip-text text-transparent">
40
+ Fullstack Development <br> Made Simple
41
+ </h1>
42
+ <p class="text-xl text-gray-400 mb-10 max-w-2xl mx-auto">
43
+ Build modern web applications with our complete fullstack solutions. From frontend to backend, we've got you covered.
44
+ </p>
45
+ <div class="flex justify-center gap-4">
46
+ <a href="/services" class="px-8 py-3 bg-primary-600 hover:bg-primary-500 rounded-lg font-medium transition-colors">
47
+ Our Services
48
+ </a>
49
+ <a href="/contact" class="px-8 py-3 border border-gray-700 hover:border-gray-600 rounded-lg font-medium transition-colors">
50
+ Contact Us
51
+ </a>
52
+ </div>
53
+ </div>
54
+ </section>
55
+
56
+ <section class="features mb-20">
57
+ <h2 class="text-3xl font-bold mb-12 text-center">Why Choose Us</h2>
58
+ <div class="grid md:grid-cols-3 gap-8">
59
+ <div class="feature-card p-6 rounded-xl bg-gray-800 hover:bg-gray-700 transition-colors">
60
+ <div class="w-12 h-12 rounded-lg bg-primary-500/20 flex items-center justify-center mb-4">
61
+ <i data-feather="code" class="text-primary-500"></i>
62
+ </div>
63
+ <h3 class="text-xl font-semibold mb-3">Modern Tech Stack</h3>
64
+ <p class="text-gray-400">We use the latest technologies like React, Node.js, and modern databases to build fast, scalable applications.</p>
65
+ </div>
66
+ <div class="feature-card p-6 rounded-xl bg-gray-800 hover:bg-gray-700 transition-colors">
67
+ <div class="w-12 h-12 rounded-lg bg-secondary-500/20 flex items-center justify-center mb-4">
68
+ <i data-feather="layers" class="text-secondary-500"></i>
69
+ </div>
70
+ <h3 class="text-xl font-semibold mb-3">Fullstack Solutions</h3>
71
+ <p class="text-gray-400">From frontend UI to backend APIs and databases - we handle everything in one seamless package.</p>
72
+ </div>
73
+ <div class="feature-card p-6 rounded-xl bg-gray-800 hover:bg-gray-700 transition-colors">
74
+ <div class="w-12 h-12 rounded-lg bg-primary-500/20 flex items-center justify-center mb-4">
75
+ <i data-feather="shield" class="text-primary-500"></i>
76
+ </div>
77
+ <h3 class="text-xl font-semibold mb-3">Security Focused</h3>
78
+ <p class="text-gray-400">We implement best security practices to protect your data and users from modern threats.</p>
79
+ </div>
80
+ </div>
81
+ </section>
82
+ </main>
83
+
84
+ <custom-footer></custom-footer>
85
+
86
+ <script src="script.js"></script>
87
+ <script>
88
+ feather.replace();
89
+ </script>
90
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
91
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
92
+ </body>
93
+ </html>
main.js ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const { app, BrowserWindow, ipcMain } = require('electron');
2
+ const path = require('path');
3
+ const isDev = require('electron-is-dev');
4
+
5
+ function createWindow() {
6
+ const win = new BrowserWindow({
7
+ width: 1200,
8
+ height: 800,
9
+ minWidth: 800,
10
+ minHeight: 600,
11
+ frame: false,
12
+ webPreferences: {
13
+ nodeIntegration: true,
14
+ contextIsolation: false,
15
+ enableRemoteModule: true,
16
+ webviewTag: true
17
+ }
18
+ });
19
+
20
+ win.loadURL(
21
+ isDev
22
+ ? 'http://localhost:3000'
23
+ : `file://${path.join(__dirname, './dist/index.html')}`
24
+ );
25
+
26
+ if (isDev) {
27
+ win.webContents.openDevTools();
28
+ }
29
+ }
30
+
31
+ app.whenReady().then(createWindow);
32
+
33
+ app.on('window-all-closed', () => {
34
+ if (process.platform !== 'darwin') {
35
+ app.quit();
36
+ }
37
+ });
38
+
39
+ app.on('activate', () => {
40
+ if (BrowserWindow.getAllWindows().length === 0) {
41
+ createWindow();
42
+ }
43
+ });
package.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```json
2
+ {
3
+ "name": "shadowstack-browser",
4
+ "version": "1.0.0",
5
+ "description": "AI-powered web browser with integrated assistant",
6
+ "main": "main.js",
7
+ "scripts": {
8
+ "start": "electron .",
9
+ "dev": "concurrently \"npm run dev:react\" \"npm run dev:electron\"",
10
+ "dev:react": "webpack serve --config webpack.react.js --mode development",
11
+ "dev:electron": "electron .",
12
+ "build": "webpack --config webpack.react.js --mode production && electron-builder"
13
+ },
14
+ "dependencies": {
15
+ "@electron/remote": "^2.1.2",
16
+ "axios": "^1.6.0",
17
+ "electron-is-dev": "^2.0.0",
18
+ "express": "^4.18.2",
19
+ "openai": "^4.20.0",
20
+ "path": "^0.12.7"
21
+ },
22
+ "devDependencies": {
23
+ "concurrently": "^8.2.0",
24
+ "electron": "^28.0.0",
25
+ "electron-builder": "^24.9.0",
26
+ "webpack": "^5.89.0",
27
+ "webpack-cli": "^5.1.4",
28
+ "webpack-dev-server": "^4.15.1"
29
+ }
30
+ }
31
+ ```
script.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Theme toggle functionality
2
+ document.addEventListener('DOMContentLoaded', () => {
3
+ // Check for saved theme preference
4
+ if (localStorage.getItem('darkMode') === 'false') {
5
+ document.documentElement.classList.remove('dark');
6
+ }
7
+
8
+ // Initialize tooltips
9
+ const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
10
+ tooltipTriggerList.map(function (tooltipTriggerEl) {
11
+ return new bootstrap.Tooltip(tooltipTriggerEl);
12
+ });
13
+ });
14
+
15
+ // Simple form validation example
16
+ function validateForm(form) {
17
+ const inputs = form.querySelectorAll('input[required], textarea[required]');
18
+ let isValid = true;
19
+
20
+ inputs.forEach(input => {
21
+ if (!input.value.trim()) {
22
+ input.classList.add('border-red-500');
23
+ isValid = false;
24
+ } else {
25
+ input.classList.remove('border-red-500');
26
+ }
27
+ });
28
+
29
+ return isValid;
30
+ }
src/App.js ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from 'react';
2
+ import Sidebar from './components/Sidebar';
3
+ import AddressBar from './components/AddressBar';
4
+ import TabBar from './components/TabBar';
5
+ import WebView from './components/WebView';
6
+ import AIAssistant from './components/AIAssistant';
7
+ import SettingsModal from './components/SettingsModal';
8
+ import BookmarksPage from './pages/BookmarksPage';
9
+ import HistoryPage from './pages/HistoryPage';
10
+ import DownloadsPage from './pages/DownloadsPage';
11
+
12
+ const App = () => {
13
+ const [tabs, setTabs] = useState([
14
+ { id: 1, title: 'New Tab', url: 'https://www.google.com', active: true }
15
+ ]);
16
+ const [activeTabId, setActiveTabId] = useState(1);
17
+ const [showAIAssistant, setShowAIAssistant] = useState(false);
18
+ const [showSettings, setShowSettings] = useState(false);
19
+ const [currentPage, setCurrentPage] = useState('browser'); // browser, bookmarks, history, downloads
20
+ const [bookmarks, setBookmarks] = useState([]);
21
+ const [history, setHistory] = useState([]);
22
+ const [downloads, setDownloads] = useState([]);
23
+
24
+ // Load data from localStorage
25
+ useEffect(() => {
26
+ const savedBookmarks = JSON.parse(localStorage.getItem('bookmarks') || '[]');
27
+ const savedHistory = JSON.parse(localStorage.getItem('history') || '[]');
28
+ const savedDownloads = JSON.parse(localStorage.getItem('downloads') || '[]');
29
+
30
+ setBookmarks(savedBookmarks);
31
+ setHistory(savedHistory);
32
+ setDownloads(savedDownloads);
33
+ }, []);
34
+
35
+ // Save data to localStorage
36
+ useEffect(() => {
37
+ localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
38
+ }, [bookmarks]);
39
+
40
+ useEffect(() => {
41
+ localStorage.setItem('history', JSON.stringify(history));
42
+ }, [history]);
43
+
44
+ useEffect(() => {
45
+ localStorage.setItem('downloads', JSON.stringify(downloads));
46
+ }, [downloads]);
47
+
48
+ const addTab = () => {
49
+ const newTab = {
50
+ id: Date.now(),
51
+ title: 'New Tab',
52
+ url: 'https://www.google.com',
53
+ active: true
54
+ };
55
+ setTabs([...tabs.map(tab => ({ ...tab, active: false })), newTab]);
56
+ setActiveTabId(newTab.id);
57
+ setCurrentPage('browser');
58
+ };
59
+
60
+ const closeTab = (id) => {
61
+ if (tabs.length <= 1) return;
62
+ const newTabs = tabs.filter(tab => tab.id !== id);
63
+ if (tabs.find(tab => tab.id === id)?.active) {
64
+ newTabs[0].active = true;
65
+ setActiveTabId(newTabs[0].id);
66
+ }
67
+ setTabs(newTabs);
68
+ };
69
+
70
+ const switchTab = (id) => {
71
+ setTabs(tabs.map(tab => ({
72
+ ...tab,
73
+ active: tab.id === id
74
+ })));
75
+ setActiveTabId(id);
76
+ };
77
+
78
+ const updateTab = (id, updates) => {
79
+ setTabs(tabs.map(tab =>
80
+ tab.id === id ? { ...tab, ...updates } : tab
81
+ ));
82
+ };
83
+
84
+ const addBookmark = (bookmark) => {
85
+ setBookmarks([...bookmarks, bookmark]);
86
+ };
87
+
88
+ const removeBookmark = (url) => {
89
+ setBookmarks(bookmarks.filter(b => b.url !== url));
90
+ };
91
+
92
+ const addToHistory = (entry) => {
93
+ setHistory([entry, ...history.slice(0, 99)]); // Keep last 100 entries
94
+ };
95
+
96
+ const addDownload = (download) => {
97
+ setDownloads([download, ...downloads]);
98
+ };
99
+
100
+ const activeTab = tabs.find(tab => tab.id === activeTabId) || tabs[0];
101
+
102
+ return (
103
+ <div className="flex h-screen bg-gray-900 text-white overflow-hidden">
104
+ <Sidebar
105
+ currentPage={currentPage}
106
+ setCurrentPage={setCurrentPage}
107
+ showAIAssistant={showAIAssistant}
108
+ setShowAIAssistant={setShowAIAssistant}
109
+ setShowSettings={setShowSettings}
110
+ addTab={addTab}
111
+ />
112
+
113
+ <div className="flex flex-col flex-1">
114
+ <AddressBar
115
+ activeTab={activeTab}
116
+ updateTab={updateTab}
117
+ addTab={addTab}
118
+ setCurrentPage={setCurrentPage}
119
+ />
120
+
121
+ <TabBar
122
+ tabs={tabs}
123
+ activeTabId={activeTabId}
124
+ switchTab={switchTab}
125
+ closeTab={closeTab}
126
+ addTab={addTab}
127
+ />
128
+
129
+ {currentPage === 'browser' ? (
130
+ <WebView
131
+ activeTab={activeTab}
132
+ updateTab={updateTab}
133
+ addToHistory={addToHistory}
134
+ addDownload={addDownload}
135
+ />
136
+ ) : currentPage === 'bookmarks' ? (
137
+ <BookmarksPage
138
+ bookmarks={bookmarks}
139
+ removeBookmark={removeBookmark}
140
+ setCurrentPage={setCurrentPage}
141
+ />
142
+ ) : currentPage === 'history' ? (
143
+ <HistoryPage
144
+ history={history}
145
+ setCurrentPage={setCurrentPage}
146
+ />
147
+ ) : (
148
+ <DownloadsPage
149
+ downloads={downloads}
150
+ setCurrentPage={setCurrentPage}
151
+ />
152
+ )}
153
+ </div>
154
+
155
+ {showAIAssistant && (
156
+ <AIAssistant
157
+ activeTab={activeTab}
158
+ onClose={() => setShowAIAssistant(false)}
159
+ />
160
+ )}
161
+
162
+ {showSettings && (
163
+ <SettingsModal
164
+ onClose={() => setShowSettings(false)}
165
+ />
166
+ )}
167
+ </div>
168
+ );
169
+ };
170
+
171
+ export default App;
src/components/AddressBar.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```javascript
2
+ import React, { useState } from 'react';
3
+ import {
4
+ ArrowLeftIcon,
5
+ ArrowRightIcon,
6
+ ArrowPathIcon,
7
+ MicrophoneIcon,
8
+ MagnifyingGlassIcon
9
+ } from '@heroicons/react/24/outline';
10
+
11
+ const AddressBar = ({ activeTab, updateTab, addTab, setCurrentPage }) => {
12
+ const [inputValue, setInputValue] = useState(activeTab?.url || '');
13
+ const [isListening, setIsListening] = useState(false);
14
+
15
+ const handleKeyDown = (e) => {
16
+ if (e.key === 'Enter') {
17
+ handleSubmit();
18
+ }
19
+ };
20
+
21
+ const handleSubmit = () => {
22
+ let url = inputValue.trim();
23
+
24
+ // If it looks like a search query, redirect to Google search
25
+ if (!url.includes('.') && url.split(' ').length > 0) {
26
+ url = `https://www.google.com/search?q=${encodeURIComponent(url)}`;
27
+ }
28
+ // If no protocol specified, add https://
29
+ else if (!url.startsWith('http://') && !url.startsWith('https://')) {
30
+ url = `https://${url}`;
31
+ }
32
+
33
+ updateTab(activeTab.id, { url });
34
+ setInputValue(url);
35
+ };
36
+
37
+ const handleVoiceSearch = () => {
38
+ if ('webkitSpeechRecognition' in window) {
39
+ const recognition = new window
src/components/Sidebar.js ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import {
3
+ HomeIcon,
4
+ BookmarkIcon,
5
+ ClockIcon,
6
+ ArrowDownTrayIcon,
7
+ Cog6ToothIcon,
8
+ ChatBubbleLeftRightIcon,
9
+ PlusIcon
10
+ } from '@heroicons/react/24/outline';
11
+
12
+ const Sidebar = ({
13
+ currentPage,
14
+ setCurrentPage,
15
+ showAIAssistant,
16
+ setShowAIAssistant,
17
+ setShowSettings,
18
+ addTab
19
+ }) => {
20
+ const menuItems = [
21
+ { id: 'home', label: 'Home', icon: HomeIcon },
22
+ { id: 'bookmarks', label: 'Bookmarks', icon: BookmarkIcon },
23
+ { id: 'history', label: 'History', icon: ClockIcon },
24
+ { id: 'downloads', label: 'Downloads', icon: ArrowDownTrayIcon },
25
+ { id: 'settings', label: 'Settings', icon: Cog6ToothIcon }
26
+ ];
27
+
28
+ return (
29
+ <div className="w-16 bg-gray-800 flex flex-col items-center py-4 space-y-6">
30
+ <div className="p-2 rounded-lg bg-indigo-600 mb-2">
31
+ <PlusIcon className="h-6 w-6 text-white" onClick={addTab} />
32
+ </div>
33
+
34
+ {menuItems.map((item) => (
35
+ <button
36
+ key={item.id}
37
+ onClick={() => {
38
+ if (item.id === 'settings') {
39
+ setShowSettings(true);
40
+ } else {
41
+ setCurrentPage(item.id);
42
+ }
43
+ }}
44
+ className={`p-2 rounded-lg transition-colors ${
45
+ currentPage === item.id ? 'bg-gray-700' : 'hover:bg-gray-700'
46
+ }`}
47
+ >
48
+ <item.icon className="h-6 w-6 text-gray-300" />
49
+ </button>
50
+ ))}
51
+
52
+ <div className="mt-auto">
53
+ <button
54
+ onClick={() => setShowAIAssistant(!showAIAssistant)}
55
+ className={`p-2 rounded-lg transition-colors ${
56
+ showAIAssistant ? 'bg-indigo-600' : 'hover:bg-gray-700'
57
+ }`}
58
+ >
59
+ <ChatBubbleLeftRightIcon className="h-6 w-6 text-gray-300" />
60
+ </button>
61
+ </div>
62
+ </div>
63
+ );
64
+ };
65
+
66
+ export default Sidebar;
src/index.css ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ body {
6
+ margin: 0;
7
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
8
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
9
+ sans-serif;
10
+ -webkit-font-smoothing: antialiased;
11
+ -moz-osx-font-smoothing: grayscale;
12
+ overflow: hidden;
13
+ }
14
+
15
+ .webview-container {
16
+ flex: 1;
17
+ position: relative;
18
+ }
19
+
20
+ webview {
21
+ width: 100%;
22
+ height: 100%;
23
+ position: absolute;
24
+ top: 0;
25
+ left: 0;
26
+ }
27
+
28
+ .shimmer {
29
+ animation: shimmer 1.5s infinite linear;
30
+ background: linear-gradient(to right, #2d3748 4%, #4a5568 25%, #2d3748 36%);
31
+ background-size: 1000px 100%;
32
+ }
33
+
34
+ @keyframes shimmer {
35
+ 0% {
36
+ background-position: -1000px 0;
37
+ }
38
+ 100% {
39
+ background-position: 1000px 0;
40
+ }
41
+ }
42
+
43
+ .neumorphic {
44
+ background: #1a202c;
45
+ box-shadow: 5px 5px 10px #0d1017, -5px -5px 10px #272e45;
46
+ border-radius: 16px;
47
+ }
48
+
49
+ .glassmorphic {
50
+ background: rgba(26, 32, 44, 0.7);
51
+ backdrop-filter: blur(10px);
52
+ border-radius: 16px;
53
+ border: 1px solid rgba(255, 255, 255, 0.1);
54
+ }
src/index.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import App from './App';
4
+ import './index.css';
5
+
6
+ const root = ReactDOM.createRoot(document.getElementById('root'));
7
+ root.render(<App />);
style.css CHANGED
@@ -1,28 +1,30 @@
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
 
28
  }
 
 
 
 
1
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
2
+
3
  body {
4
+ font-family: 'Inter', sans-serif;
 
5
  }
6
 
7
+ .feature-card:hover i {
8
+ transform: scale(1.1);
9
+ transition: transform 0.2s ease;
10
  }
11
 
12
+ /* Smooth scrolling */
13
+ html {
14
+ scroll-behavior: smooth;
 
 
15
  }
16
 
17
+ /* Custom scrollbar */
18
+ ::-webkit-scrollbar {
19
+ width: 8px;
 
 
 
20
  }
21
+ ::-webkit-scrollbar-track {
22
+ background: #1e1e1e;
23
+ }
24
+ ::-webkit-scrollbar-thumb {
25
+ background: #7c3aed;
26
+ border-radius: 4px;
27
  }
28
+ ::-webkit-scrollbar-thumb:hover {
29
+ background: #6d28d9;
30
+ }
webpack.react.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const path = require('path');
2
+
3
+ module.exports = {
4
+ entry: './src/index.js',
5
+ output: {
6
+ path: path.resolve(__dirname, 'dist'),
7
+ filename: 'bundle.js'
8
+ },
9
+ module: {
10
+ rules: [
11
+ {
12
+ test: /\.(js|jsx)$/,
13
+ exclude: /node_modules/,
14
+ use: {
15
+ loader: 'babel-loader',
16
+ options: {
17
+ presets: ['@babel/preset-env', '@babel/preset-react']
18
+ }
19
+ }
20
+ },
21
+ {
22
+ test: /\.css$/,
23
+ use: ['style-loader', 'css-loader']
24
+ }
25
+ ]
26
+ },
27
+ resolve: {
28
+ extensions: ['.js', '.jsx']
29
+ },
30
+ devServer: {
31
+ static: {
32
+ directory: path.join(__dirname, 'dist')
33
+ },
34
+ compress: true,
35
+ port: 3000
36
+ }
37
+ };