diff --git a/package-lock.json b/package-lock.json index 49911b2..89c7c92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "lucide-react": "^0.544.0", "react": "^19.1.1", "react-dom": "^19.1.1", + "react-icons": "^5.5.0", "react-router-dom": "^7.9.1", "recharts": "^3.2.1" }, @@ -4257,6 +4258,15 @@ "react": "^19.1.1" } }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "19.1.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz", diff --git a/package.json b/package.json index 176d6a7..07db6b6 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "lucide-react": "^0.544.0", "react": "^19.1.1", "react-dom": "^19.1.1", + "react-icons": "^5.5.0", "react-router-dom": "^7.9.1", "recharts": "^3.2.1" }, diff --git a/src/App.tsx b/src/App.tsx index cd45764..c2c67ce 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,7 @@ import Footer from './components/shared/Footer' import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Dashboard from './pages/Dashboard'; import Portfolio from './pages/Portfolio'; - +import Analysis from './pages/Analysis'; import Settings from './pages/Settings'; import Strategy from './pages/Strategy'; import Login from './pages/login'; @@ -19,16 +19,18 @@ function App() { } /> - } /> + {/* } /> } /> + } /> } /> } /> + */} - - {/* } /> + } /> } /> } /> - } /> */} + } /> + } /> diff --git a/src/assets/image.png b/src/assets/image.png new file mode 100644 index 0000000..237f21c Binary files /dev/null and b/src/assets/image.png differ diff --git a/src/components/Analysis/AnalysisSearch.tsx b/src/components/Analysis/AnalysisSearch.tsx new file mode 100644 index 0000000..229fbd2 --- /dev/null +++ b/src/components/Analysis/AnalysisSearch.tsx @@ -0,0 +1,77 @@ +import { useState } from 'react'; +import { Search } from 'lucide-react'; + +const AnalysisSearch = () => { + const [aiq, setAiq] = useState('10'); + const [website, setWebsite] = useState('mysite.com'); + + const handleAnalyze = () => { + console.log('Analyzing:', { aiq, website }); + }; + + return ( +
+
+
+
+ + setAiq(e.target.value)} + className="w-16 text-center bg-transparent text-xl font-semibold text-gray-900 focus:outline-none" + min="1" + max="100" + /> +
+ +
+ setWebsite(e.target.value)} + placeholder="Enter website URL" + className="w-full px-6 py-4 bg-gray-50 border-2 border-gray-200 rounded-xl text-gray-900 font-medium focus:outline-none focus:border-blue-500 focus:ring-4 focus:ring-blue-100 transition-all" + /> +
+ + + +
+
+ + +
+ +
+
+ AIQ Score: + Measures AI visibility and authority +
+
+
+
+ ); +}; + +export default AnalysisSearch; + diff --git a/src/components/Analysis/BecomeTheSource.tsx b/src/components/Analysis/BecomeTheSource.tsx new file mode 100644 index 0000000..69fb448 --- /dev/null +++ b/src/components/Analysis/BecomeTheSource.tsx @@ -0,0 +1,150 @@ +import { PieChart, Pie, Cell, ResponsiveContainer } from 'recharts'; +import { Info, Zap } from 'lucide-react'; +import type { IconType } from 'react-icons'; +import { + FaBehance, FaPinterest, FaTrello, FaFoursquare, + FaWordpress, FaMedium, FaStackOverflow, + FaYoutube, FaPodcast, FaQuora, FaReddit, FaTelegram +} from 'react-icons/fa'; +import { SiAboutdotme } from 'react-icons/si'; + +type SocialIconItem = + | { Icon: IconType; className: string } + | { icon: string; className: string }; + +const data = [ + { name: 'Branded Aesthetics Social Signals', value: 30, color: '#4E73DF' }, + { name: 'Local + Medical-Cosmetic Citations', value: 30, color: '#5A9FFF' }, + { name: 'Web 2.0 Microblogging Sites', value: 20, color: '#36B37E' }, + { name: 'Multimedia Content & Beauty Visuals', value: 20, color: '#FDB91A' }, + { name: 'Community and UGC Signals', value: 10, color: '#EF5350' }, +]; + +const socialIcons: SocialIconItem[][] = [ + [ + { Icon: FaBehance, className: "text-blue-600" }, + { Icon: FaPinterest, className: "text-red-600" }, + { Icon: FaTrello, className: "text-red-500" } + ], + [ + { Icon: FaFoursquare, className: "text-pink-500" }, + { Icon: FaMedium, className: "text-yellow-500" }, + { Icon: SiAboutdotme, className: "text-cyan-400" } + ], + [ + { Icon: FaWordpress, className: "text-blue-700" }, + { Icon: FaMedium, className: "text-gray-900" }, + { Icon: FaStackOverflow, className: "text-orange-500" } + ], + [ + { Icon: FaYoutube, className: "text-red-600" }, + { Icon: FaPodcast, className: "text-purple-500" }, + { icon: '⦿', className: "text-red-500 text-2xl" } + ], + [ + { Icon: FaReddit, className: "text-orange-600" }, + { Icon: FaQuora, className: "text-red-700" }, + { Icon: FaTelegram, className: "text-blue-400" } + ], +]; + +const BecomeTheSource = () => { + return ( +
+
+

+ Become the Source +

+

+ Custom Authority Beacons & Backlink Strategy, Tailored for{' '} + Medical Spas +

+
+ +
+
+
+ + + + {data.map((entry, index) => { + return ; + })} + + + +
+ + +
+ +
+ {data.map((item, index) => { + return ( +
+
+
+ {item.value}% + +
+ {item.name} +
+ ); + })} +
+
+
+ {socialIcons.map((row, rowIndex) => { + return ( +
+ {row.map((item, iconIndex) => { + return ( +
+ {'Icon' in item ? ( + (() => { + const IconComponent = item.Icon; + return ; + })() + ) : ( + {item.icon} + )} +
+ ); + })} +
+ ); + })} +
+
+
+ + +
+ ); +}; + +export default BecomeTheSource; + diff --git a/src/components/Analysis/SourcesChart.tsx b/src/components/Analysis/SourcesChart.tsx new file mode 100644 index 0000000..3f70320 --- /dev/null +++ b/src/components/Analysis/SourcesChart.tsx @@ -0,0 +1,85 @@ +import { PieChart, Pie, Cell, ResponsiveContainer, Legend } from 'recharts'; +import { Lightbulb } from 'lucide-react'; + +const data = [ + { name: 'Consumer Health Giants', value: 40, color: '#6B8FE8' }, + { name: 'Mainstream Media Sections', value: 30, color: '#4E73DF' }, + { name: 'Elite Medical Journals', value: 20, color: '#2E5BC7' }, + { name: 'Specialty Platforms', value: 10, color: '#FDB91A' }, + { name: 'Professional/Academic Crossovers', value: 3, color: '#EF5350' }, +]; + +const SourcesChart = () => { + return ( +
+

+ AI Frequently Cited Sources in Healthcare +

+ +
+
+ + + + {data.map((entry, index) => ( + + ))} + + + +
+ +
+ {data.map((item, index) => ( +
+
+
+ + {item.value}% + + {item.name} +
+
+ ))} +
+
+ +
+
+ +
+

+ How AI and LLMs Choose Their Sources +

+

+ Our analysis reveals distinct patterns in how leading AIs source and prioritize + industry information. For example, ChatGPT leans heavily on user-generated content, + while Google's AI Overviews favors authoritative tech review sites. Across the + board, backlink quality plays a crucial role, with...{' '} + +

+
+
+
+
+ ); +}; + +export default SourcesChart; + diff --git a/src/components/Analysis/VisibilityAnalysis.tsx b/src/components/Analysis/VisibilityAnalysis.tsx new file mode 100644 index 0000000..5140c3b --- /dev/null +++ b/src/components/Analysis/VisibilityAnalysis.tsx @@ -0,0 +1,125 @@ +import { Info, Share2 } from 'lucide-react'; +import { useState } from 'react'; + +type Tab = 'aio' | 'backlinks' | 'gpos' | 'maps' | 'ai-overview' | 'chatgpt' | 'gemini' | 'perplexity'; + +const VisibilityAnalysis = () => { + const [activeTab, setActiveTab] = useState('aio'); + + const tabs = [ + { id: 'aio' as Tab, label: 'AIO Health', hasInfo: true }, + { id: 'backlinks' as Tab, label: 'Backlinks', hasInfo: true }, + { id: 'gpos' as Tab, label: 'G Pos #' }, + { id: 'maps' as Tab, label: 'Maps' }, + { id: 'ai-overview' as Tab, label: 'AI Overview' }, + { id: 'chatgpt' as Tab, label: 'Chat GPT' }, + { id: 'gemini' as Tab, label: 'Gemini' }, + { id: 'perplexity' as Tab, label: 'Perplexity' }, + ]; + + return ( +
+

Analysis of Visibility

+ +
+

BH Medical Spa of Beverly Hills

+
+ + Sector: Healthcare + + + Industry: Medical Spa + +
+
+ +
+
+ {tabs.map((tab) => { + return ( + + ); + })} +
+ +
+ +
+
+
+ 24% +
+ +
+
+ 14% + 50/370 links +
+ +
+
G
+ 5 +
+ +
+
📍
+ 8 +
+ +
+
+ + + + +
+ Invisible +
+ +
+
+ + + +
+ Invisible +
+ +
+
+ + + +
+ Invisible +
+ +
+
+ + + +
+ Invisible +
+
+
+ ); +}; + +export default VisibilityAnalysis; + diff --git a/src/components/shared/Header.tsx b/src/components/shared/Header.tsx index 87ed28c..5ddaf6a 100644 --- a/src/components/shared/Header.tsx +++ b/src/components/shared/Header.tsx @@ -49,9 +49,9 @@ const BookOpen = () => { const BookOpenLight = () => { return ( - + - + ) } @@ -87,12 +87,22 @@ const Header = () => { const toggleMenu = () => setIsMenuOpen(!isMenuOpen); const toggleMobileNav = () => setIsMobileNavOpen(!isMobileNavOpen); - + const AnalysisIcon = () => { + return ( + + + + + ) + } + const navLinks = [ { name: 'Dashboard', to: '/', icon: LayoutDashboard, iconLight: LayoutDashboardLight }, { name: 'Portfolio', to: '/portfolio', icon: BookOpen, iconLight: BookOpenLight }, { name: 'Strategy', to: '/strategy', icon: CalendarDays, iconLight: CalendarDaysLight }, - ]; + { name: 'Analysis', to: '/analysis', icon: AnalysisIcon, iconLight: AnalysisIcon }, + ]; + const menuItems = [ { name: 'Edit Profile', icon: User, to: '/profile' }, @@ -158,13 +168,13 @@ const Header = () => {
{/* Add Keyword Button */} - + -
+
{/* Profile Dropdown */}
@@ -248,9 +258,9 @@ const Header = () => { Add Keyword */} - -
+ +
{/* Profile menu */} diff --git a/src/pages/Analysis.tsx b/src/pages/Analysis.tsx new file mode 100644 index 0000000..ea2974f --- /dev/null +++ b/src/pages/Analysis.tsx @@ -0,0 +1,22 @@ +import ContainerPage from "../components/shared/ContainerPage"; +import SourcesChart from "../components/Analysis/SourcesChart"; +import AnalysisSearch from "../components/Analysis/AnalysisSearch"; +import BecomeTheSource from "../components/Analysis/BecomeTheSource"; +import VisibilityAnalysis from "../components/Analysis/VisibilityAnalysis"; + +const Analysis = () => { + return ( + +
+ + +
+ + +
+
+
+ ); +}; + +export default Analysis;