diff --git a/package-lock.json b/package-lock.json index abd5913..e181d2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,34 @@ { "name": "orgexplorer", - "version": "2.0.0", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orgexplorer", - "version": "2.0.0", + "version": "1.0.0", "dependencies": { + "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/vite": "^4.3.0", + "@tanstack/react-query": "^5.100.14", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "d3": "^7.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.3.0", "react-router-dom": "^6.26.2", "recharts": "^2.12.7", + "tailwind-merge": "^3.6.0", "tailwindcss": "^4.3.0" }, "devDependencies": { + "@types/node": "^25.9.1", + "@types/react": "^19.2.15", + "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^4.3.1", + "prettier": "^3.8.3", + "typescript": "^6.0.3", "vite": "^5.4.6" } }, @@ -726,10 +736,43 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@remix-run/router": { - "version": "1.23.2", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz", - "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.3.tgz", + "integrity": "sha512-4An71tdz9X8+3sI4Qqqd2LWd9vS39J7sqd9EU4Scw7TJE/qB10Flv/UuqbPVgfQV9XoK8Np6jNquZitnZq5i+Q==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -1324,6 +1367,32 @@ "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, + "node_modules/@tanstack/query-core": { + "version": "5.100.14", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.14.tgz", + "integrity": "sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.100.14", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.14.tgz", + "integrity": "sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.100.14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1438,6 +1507,36 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, + "node_modules/@types/node": { + "version": "25.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", + "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@types/react": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.15.tgz", + "integrity": "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, "node_modules/@vitejs/plugin-react": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", @@ -1527,6 +1626,18 @@ ], "license": "CC-BY-4.0" }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -2019,9 +2130,9 @@ "license": "ISC" }, "node_modules/enhanced-resolve": { - "version": "5.22.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.2.tgz", - "integrity": "sha512-0rxICaFZ7NQho/sHely2bvOPRP0Eu2B0NZ9zM54YvRvWMn7jfz3DmnOZDR9LlXDdDcqntAVc6Hfy4gr/tdH/Ag==", + "version": "5.22.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.1.tgz", + "integrity": "sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -2436,9 +2547,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/loose-envify": { @@ -2480,9 +2591,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "funding": [ { "type": "github", @@ -2520,9 +2631,9 @@ "license": "ISC" }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", "funding": [ { "type": "opencollective", @@ -2539,7 +2650,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -2547,6 +2658,22 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -2615,12 +2742,12 @@ } }, "node_modules/react-router": { - "version": "6.30.3", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz", - "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==", + "version": "6.30.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.4.tgz", + "integrity": "sha512-SVUsDe+DybHM/WmYKIVYhZh1o5Dcuf16yM6WjG02Q9XVFMZIJyHYhwrr6bFBXZkVP6z69kNkMyBCujt8FaFLJA==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.23.2" + "@remix-run/router": "1.23.3" }, "engines": { "node": ">=14.0.0" @@ -2630,13 +2757,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.30.3", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz", - "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==", + "version": "6.30.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.4.tgz", + "integrity": "sha512-q4HvNl+mmDdkS0g+MqiBZNteQJCuimWoOyHMy4T/RQLAn9Z29+E91QXRaxOujeMl2HTzRSS0KFPd7lxX3PjV0Q==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.23.2", - "react-router": "6.30.3" + "@remix-run/router": "1.23.3", + "react-router": "6.30.4" }, "engines": { "node": ">=14.0.0" @@ -2799,6 +2926,16 @@ "node": ">=0.10.0" } }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", @@ -2824,6 +2961,27 @@ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "license": "MIT" }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "devOptional": true, + "license": "MIT" + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", diff --git a/package.json b/package.json index 2734074..3e14d9f 100644 --- a/package.json +++ b/package.json @@ -5,21 +5,33 @@ "type": "module", "scripts": { "dev": "vite", - "build": "vite build", - "preview": "vite preview" + "build": "tsc -b && vite build", + "preview": "vite preview", + "format": "prettier . --write", + "format:check": "prettier . --check" }, "dependencies": { + "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/vite": "^4.3.0", + "@tanstack/react-query": "^5.100.14", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "d3": "^7.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.3.0", "react-router-dom": "^6.26.2", "recharts": "^2.12.7", + "tailwind-merge": "^3.6.0", "tailwindcss": "^4.3.0" }, "devDependencies": { + "@types/node": "^25.9.1", + "@types/react": "^19.2.15", + "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^4.3.1", + "prettier": "^3.8.3", + "typescript": "^6.0.3", "vite": "^5.4.6" } } diff --git a/src/App.jsx b/src/App.jsx index fd61e4f..77a2a04 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,28 +1,16 @@ -import React from 'react' -import { Routes, Route, Navigate } from 'react-router-dom' -import { AppProvider } from './context/AppContext' -import Navbar from './components/Navbar' -import RateLimitBanner from './components/RateLimitBanner' -import HomePage from './pages/HomePage' -import OverviewPage from './pages/OverviewPage' -import RepositoriesPage from './pages/RepositoriesPage' -import ContributorsPage from './pages/ContributorsPage' -import NetworkPage from './pages/NetworkPage' -import AnalyticsPage from './pages/AnalyticsPage' -import GovernancePage from './pages/GovernancePage' -import SettingsPage from './pages/SettingsPage' -import Footer from './components/layout/Footer' +import React from "react"; +import { Routes, Route, Navigate } from "react-router-dom"; +import { AppProvider } from "./context/AppContext"; +import HomePage from "./pages/HomePage"; +import OverviewPage from "./pages/OverviewPage"; +import RepositoriesPage from "./pages/RepositoriesPage"; +import ContributorsPage from "./pages/ContributorsPage"; +import NetworkPage from "./pages/NetworkPage"; +import AnalyticsPage from "./pages/AnalyticsPage"; +import GovernancePage from "./pages/GovernancePage"; +import SettingsPage from "./pages/SettingsPage"; +import Layout from "./components/layout/Layout"; -function Layout({ children }) { - return ( -
- - -
{children}
-
- ) -} export default function App() { return ( diff --git a/public/org-explorer-logo.svg b/src/assets/logos/org-explorer-logo.svg similarity index 100% rename from public/org-explorer-logo.svg rename to src/assets/logos/org-explorer-logo.svg diff --git a/src/components/Home/HeroSection.jsx b/src/components/Home/HeroSection.jsx new file mode 100644 index 0000000..ad5bfa6 --- /dev/null +++ b/src/components/Home/HeroSection.jsx @@ -0,0 +1,71 @@ +import OrgSearchBox from "./OrgSearchBox"; +import RecentSearches from "./RecentSearches"; +import QuickAccess from "./QuickAccess"; + +import { Spinner } from "@/components/UI"; + +export default function HeroSection(props) { + const { + loading, + loadMsg, + error, + recent, + go, + quickExploreItems, + handleSelectOrg, + } = props; + + return ( +
+
+ +
+

+ Architect Your + Insights +

+ +

+ Unified analytics across one or many GitHub organizations. +

+ + + +

+ Type an org name and press Enter or comma to add. +

+ + {error && ( +

+ {error} +

+ )} + + {loading && ( +
+ +

{loadMsg}

+
+ )} + + {recent.length > 0 && !loading && ( + + )} + + {!loading && ( + + )} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/Home/OrgExplorerFeatures.jsx b/src/components/Home/OrgExplorerFeatures.jsx new file mode 100644 index 0000000..f1fc34d --- /dev/null +++ b/src/components/Home/OrgExplorerFeatures.jsx @@ -0,0 +1,229 @@ + +export default function OrgExplorerFeatures() { + const features = [ + { + title: "Interactive Org Visualization", + desc: "Explore repositories, teams, and contributors through a dynamic relationship graph designed for instant understanding.", + bullets: [ + "Live node graph", + "Repository mapping", + "Contributor insights", + ], + visual: ( +
+
+ +
+ + {[...Array(8)].map((_, i) => ( +
+ ))} + + + + + + + + +
+ 142 repositories mapped +
+
+ ), + }, + { + title: "Zero Backend Delay", + desc: "Everything runs instantly with direct GitHub API interactions and optimized client-side rendering.", + bullets: [ + "Instant updates", + "No server bottleneck", + "Fast local rendering", + ], + visual: ( +
+
+ +
+
+ GitHub Data Sync + 0.2s +
+ +
+
+
+ +
+ {["Repos", "Teams", "Contributors"].map((item) => ( +
+ {item} +
+ ))} +
+
+
+ ), + }, + { + title: "Secure PAT Authentication", + desc: "Your Personal Access Tokens stay encrypted and stored locally for maximum privacy and security.", + bullets: [ + "Local-only storage", + "Encrypted handling", + "Privacy-first architecture", + ], + visual: ( +
+
+ +
+
+
+ +
+
🔒
+

+ Secure Local Authentication +

+
+
+
+
+ ), + }, + { + title: "Auto Save & Auto Refresh", + desc: "Your workspace updates automatically while preserving every interaction in real time.", + bullets: [ + "Background syncing", + "Real-time refresh", + "Persistent workspace state", + ], + visual: ( +
+
+ +
+
+ ↻ +
+ +
+
+ ✓ Workspace Auto-Saved +
+ +
+ ✓ GitHub Data Refreshed +
+
+
+
+ ), + }, + { + title: "One-Click Exporting", + desc: "Export organization graphs and analytics instantly in multiple formats for sharing and documentation.", + bullets: ["PNG & SVG export", "JSON snapshots", "Instant downloads"], + visual: ( +
+
+ +
+
+
+ Export Workspace +
+ +
+ {["PNG", "SVG", "JSON"].map((item) => ( +
+ .{item.toLowerCase()} + +
+ ))} +
+
+
+
+ ), + }, + ]; + + return ( +
+
+
+

+ Core Features +

+ +

+ Built for exploring GitHub organizations visually. +

+ +

+ A premium developer experience focused on performance, privacy, + automation, and visual clarity. +

+
+ +
+ {features.map((feature, index) => ( +
+
+
+
+ 0{index + 1} +
+ +

+ {feature.title} +

+ +

+ {feature.desc} +

+ +
+ {feature.bullets.map((bullet) => ( +
+
+ {bullet} +
+ ))} +
+
+ +
{feature.visual}
+
+
+ ))} +
+
+
+ ); +} diff --git a/src/components/Home/OrgSearchBox.jsx b/src/components/Home/OrgSearchBox.jsx new file mode 100644 index 0000000..0d520ee --- /dev/null +++ b/src/components/Home/OrgSearchBox.jsx @@ -0,0 +1,92 @@ +import { FiSearch, FiX } from "react-icons/fi"; +import { BsArrowRight } from "react-icons/bs"; + +import { Button } from "@/components/ui/Button"; + +import SearchSuggestions from "./SearchSuggestions"; + +export default function OrgSearchBox({ + input, + setInput, + chips, + addChip, + removeChip, + handleKey, + handleSubmit, + showSuggestions, + setShowSuggestions, + setSelectedIndex, + filteredSuggestions, + selectedIndex, + isLoading, + handleSelectOrg, +}) { + return ( +
+
+
+ + {chips.map((c) => ( + + {c} + + removeChip(c)} + /> + + ))} + + setShowSuggestions(true)} + onBlur={() => { + setTimeout(() => { + setShowSuggestions(false); + }, 200); + + input.trim() && addChip(input); + }} + onChange={(e) => { + setInput(e.target.value); + setSelectedIndex(-1); + }} + onKeyDown={handleKey} + className="w-full bg-transparent text-sm text-white placeholder:text-zinc-500 focus:outline-none md:text-base" + /> +
+ + +
+ + +
+ ); +} diff --git a/src/components/Home/QuickAccess.jsx b/src/components/Home/QuickAccess.jsx new file mode 100644 index 0000000..43a9b45 --- /dev/null +++ b/src/components/Home/QuickAccess.jsx @@ -0,0 +1,28 @@ +import { BsArrowRight } from "react-icons/bs"; + +export default function QuickAccess({ items, handleSelectOrg }) { + return ( +
+

+ Quick Explore Access +

+ +
+ {items.map((item) => ( + + ))} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/Home/RecentSearches.jsx b/src/components/Home/RecentSearches.jsx new file mode 100644 index 0000000..38a17e5 --- /dev/null +++ b/src/components/Home/RecentSearches.jsx @@ -0,0 +1,38 @@ +import { BsArrowRight } from "react-icons/bs"; +import { cn } from "@/lib/utils"; + +export default function RecentSearches({ recent, go }) { + return ( +
+
+
+ + + Recent Searches + + +
+
+ +
+ {recent.map((r) => ( + + ))} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/Home/SearchSuggestions.jsx b/src/components/Home/SearchSuggestions.jsx new file mode 100644 index 0000000..8d0991e --- /dev/null +++ b/src/components/Home/SearchSuggestions.jsx @@ -0,0 +1,64 @@ +import { BsArrowRight } from "react-icons/bs"; +import { cn } from "@/lib/utils"; + +export default function SearchSuggestions({ + showSuggestions, + input, + isLoading, + filteredSuggestions, + selectedIndex, + handleSelectOrg, + addChip, +}) { + if (!showSuggestions || !input.trim()) return null; + + return ( +
+ {isLoading ? ( +
+ Searching organizations... +
+ ) : filteredSuggestions.length > 0 ? ( + filteredSuggestions.map((org, index) => ( + + )) + ) : ( +
+ No organization found +
+ )} +
+ ); +} diff --git a/src/components/Home/StatsSection.jsx b/src/components/Home/StatsSection.jsx new file mode 100644 index 0000000..e627d90 --- /dev/null +++ b/src/components/Home/StatsSection.jsx @@ -0,0 +1,53 @@ +import React from "react"; + +function StatsSection() { + return ( +
+
+
+ 5,000 + +
+

+ Resource Load +

+ +

+ Girth With PAT +

+
+
+ +
+ 1HR + +
+

+ Data Freshness +

+ +

+ Intelligent Cache +

+
+
+ +
+ ZERO + +
+

+ Engine Efficiency +

+ +

+ Backend Latency +

+
+
+
+
+ ); +} + +export default StatsSection; diff --git a/src/components/layout/Footer.jsx b/src/components/layout/Footer.tsx similarity index 64% rename from src/components/layout/Footer.jsx rename to src/components/layout/Footer.tsx index 6e6f620..39f7f01 100644 --- a/src/components/layout/Footer.jsx +++ b/src/components/layout/Footer.tsx @@ -62,7 +62,7 @@ const socialLinks = [ export default function Footer() { return ( -