Analysis Page
هذا الالتزام موجود في:
10
package-lock.json
مولّد
10
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",
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
12
src/App.tsx
12
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() {
|
||||
<Routes>
|
||||
<Route path="/login" element={<Login />} />
|
||||
|
||||
<Route path="/" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
|
||||
{/* <Route path="/" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
|
||||
<Route path="/portfolio" element={<ProtectedRoute><Portfolio /></ProtectedRoute>} />
|
||||
<Route path="/analysis" element={<ProtectedRoute><Analysis /></ProtectedRoute>} />
|
||||
<Route path="/strategy" element={<ProtectedRoute><Strategy /></ProtectedRoute>} />
|
||||
<Route path="/settings" element={<ProtectedRoute><Settings /></ProtectedRoute>} />
|
||||
*/}
|
||||
|
||||
|
||||
{/* <Route path="/" element={<Dashboard />} />
|
||||
<Route path="/" element={<Dashboard />} />
|
||||
<Route path="/portfolio" element={<Portfolio />} />
|
||||
<Route path="/strategy" element={<Strategy />} />
|
||||
<Route path="/settings" element={<Settings />} /> */}
|
||||
<Route path="/settings" element={<Settings />} />
|
||||
<Route path="/analysis" element={<Analysis />} />
|
||||
|
||||
|
||||
</Routes>
|
||||
|
||||
ثنائية
src/assets/image.png
Normal file
ثنائية
src/assets/image.png
Normal file
ملف ثنائي غير معروض.
|
بعد العرض: | الارتفاع: | الحجم: 96 KiB |
77
src/components/Analysis/AnalysisSearch.tsx
Normal file
77
src/components/Analysis/AnalysisSearch.tsx
Normal file
@@ -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 (
|
||||
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 p-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div className="flex flex-col md:flex-row items-center gap-4">
|
||||
<div className="flex items-center gap-3 bg-gray-50 rounded-xl px-6 py-4 border-2 border-gray-200">
|
||||
<label htmlFor="aiq" className="text-gray-700 font-medium">
|
||||
AIQ
|
||||
</label>
|
||||
<input
|
||||
id="aiq"
|
||||
type="number"
|
||||
value={aiq}
|
||||
onChange={(e) => 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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 w-full md:w-auto relative">
|
||||
<input
|
||||
type="text"
|
||||
value={website}
|
||||
onChange={(e) => 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"
|
||||
/>
|
||||
<div className="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400">
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M19 9l-7 7-7-7"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={handleAnalyze}
|
||||
className="flex items-center gap-2 px-8 py-4 bg-white hover:bg-gray-100 text-gray-900 font-medium rounded-xl transition-all shadow-lg active:scale-95"
|
||||
>
|
||||
<Search className="w-5 h-5" />
|
||||
Analyze
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex items-center justify-center gap-2 text-sm text-gray-500">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="font-medium text-gray-700">AIQ Score:</span>
|
||||
<span>Measures AI visibility and authority</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AnalysisSearch;
|
||||
|
||||
150
src/components/Analysis/BecomeTheSource.tsx
Normal file
150
src/components/Analysis/BecomeTheSource.tsx
Normal file
@@ -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 (
|
||||
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 p-8">
|
||||
<div className="mb-8">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-2">
|
||||
Become the Source
|
||||
</h2>
|
||||
<p className="text-gray-500">
|
||||
Custom Authority Beacons & Backlink Strategy, Tailored for{' '}
|
||||
<span className="text-gray-900 font-semibold">Medical Spas</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center mb-8">
|
||||
<div className="space-y-4 fl ">
|
||||
<div className="h-80 w-[342px] flex items-center justify-center">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={data}
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
innerRadius={80}
|
||||
outerRadius={140}
|
||||
paddingAngle={2}
|
||||
dataKey="value"
|
||||
>
|
||||
{data.map((entry, index) => {
|
||||
return <Cell key={`cell-${index}`} fill={entry.color} />;
|
||||
})}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
{data.map((item, index) => {
|
||||
return (
|
||||
<div key={index} className="flex flex-col items-start gap-1">
|
||||
<div className="flex items-center gap-1">
|
||||
<div
|
||||
className="w-3 h-3 rounded-full flex-shrink-0"
|
||||
style={{ backgroundColor: item.color }}
|
||||
/>
|
||||
<span className="text-lg font-bold text-gray-900">{item.value}%</span>
|
||||
<Info className="w-4 h-4 text-gray-400" />
|
||||
</div>
|
||||
<span className="text-sm text-gray-700">{item.name}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="flex flex-col gap-3">
|
||||
{socialIcons.map((row, rowIndex) => {
|
||||
return (
|
||||
<div key={rowIndex} className="flex gap-0">
|
||||
{row.map((item, iconIndex) => {
|
||||
return (
|
||||
<div
|
||||
key={iconIndex}
|
||||
className="w-10 h-10 rounded-xl ?flex items-center justify-center text-2xl"
|
||||
>
|
||||
{'Icon' in item ? (
|
||||
(() => {
|
||||
const IconComponent = item.Icon;
|
||||
return <IconComponent className={item.className} />;
|
||||
})()
|
||||
) : (
|
||||
<span className={item.className}>{item.icon}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className="w-[65%] px-6 rounded-2xl bg-white border-4 border-transparent bg-gradient-to-r from-blue-500 via-red-500 via-orange-400 via-yellow-400 to-green-500 bg-clip-padding relative group hover:shadow-xl transition-all py-6 mx-auto">
|
||||
<div className="absolute inset-0 bg-white rounded-xl m-[3px] flex items-center justify-center gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-blue-600 flex items-center justify-center">
|
||||
<Zap className="w-5 h-5 text-white fill-white" />
|
||||
</div>
|
||||
<span className="text-md font-semibold text-gray-900">
|
||||
Add your Keywords and Become the Source
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BecomeTheSource;
|
||||
|
||||
85
src/components/Analysis/SourcesChart.tsx
Normal file
85
src/components/Analysis/SourcesChart.tsx
Normal file
@@ -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 (
|
||||
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 p-8">
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-8">
|
||||
AI Frequently Cited Sources in Healthcare
|
||||
</h2>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-8 items-center">
|
||||
<div className="h-80 flex items-center justify-center">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={data}
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
innerRadius={80}
|
||||
outerRadius={140}
|
||||
paddingAngle={2}
|
||||
dataKey="value"
|
||||
>
|
||||
{data.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
{data.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center gap-4 p-4 rounded-xl bg-gray-50 hover:bg-gray-100 transition-colors"
|
||||
>
|
||||
<div
|
||||
className="w-3 h-3 rounded-full flex-shrink-0"
|
||||
style={{ backgroundColor: item.color }}
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<span className="text-2xl font-bold text-gray-900">
|
||||
{item.value}%
|
||||
</span>
|
||||
<span className="ml-2 text-gray-600">{item.name}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 bg-blue-50 rounded-xl p-6">
|
||||
<div className="flex items-start gap-3">
|
||||
<Lightbulb className="w-6 h-6 text-blue-600 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-900 mb-2">
|
||||
How AI and LLMs Choose Their Sources
|
||||
</h3>
|
||||
<p className="text-gray-700 leading-relaxed">
|
||||
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...{' '}
|
||||
<button className="text-blue-600 font-medium hover:text-blue-700">
|
||||
read more
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SourcesChart;
|
||||
|
||||
125
src/components/Analysis/VisibilityAnalysis.tsx
Normal file
125
src/components/Analysis/VisibilityAnalysis.tsx
Normal file
@@ -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<Tab>('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 (
|
||||
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 p-8">
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-6">Analysis of Visibility</h2>
|
||||
|
||||
<div className="mb-6">
|
||||
<h3 className="text-xl font-bold text-gray-900">BH Medical Spa of Beverly Hills</h3>
|
||||
<div className="flex items-center gap-4 text-sm text-gray-600 mt-1">
|
||||
<span>
|
||||
<span className="font-medium">Sector:</span> Healthcare
|
||||
</span>
|
||||
<span>
|
||||
<span className="font-medium">Industry:</span> Medical Spa
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between gap-4 mb-6 overflow-x-auto pb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
{tabs.map((tab) => {
|
||||
return (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setActiveTab(tab.id)}
|
||||
className={`px-4 py-2 rounded-lg font-medium text-sm whitespace-nowrap flex items-center gap-1 transition-colors ${
|
||||
activeTab === tab.id
|
||||
? 'bg-gray-900 text-white'
|
||||
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
||||
}`}
|
||||
>
|
||||
{tab.label}
|
||||
{tab.hasInfo && <Info className="w-3 h-3" />}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<button className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-gray-700 hover:text-gray-900 transition-colors whitespace-nowrap">
|
||||
<Share2 className="w-4 h-4" />
|
||||
Share
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-8 gap-3">
|
||||
<div className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl min-h-[100px]">
|
||||
<div className="w-10 h-10 mb-2 rounded-full border-4 border-blue-500 border-t-transparent animate-[spin_3s_linear_infinite]" />
|
||||
<span className="text-xl font-bold text-gray-900">24%</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl min-h-[100px]">
|
||||
<div className="w-10 h-10 mb-2 rounded-full border-4 border-blue-500 border-t-transparent animate-[spin_3s_linear_infinite]" />
|
||||
<span className="text-xl font-bold text-gray-900">14%</span>
|
||||
<span className="text-xs text-gray-500 mt-1">50/370 links</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl min-h-[100px]">
|
||||
<div className="w-8 h-8 mb-2 flex items-center justify-center text-2xl font-bold text-blue-600">G</div>
|
||||
<span className="text-xl font-bold text-gray-900">5</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl min-h-[100px]">
|
||||
<div className="w-8 h-8 mb-2 text-2xl">📍</div>
|
||||
<span className="text-xl font-bold text-gray-900">8</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl min-h-[100px]">
|
||||
<div className="w-8 h-8 mb-2 flex items-center justify-center">
|
||||
<svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-xs text-gray-500">Invisible</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl min-h-[100px]">
|
||||
<div className="w-8 h-8 mb-2 flex items-center justify-center">
|
||||
<svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-xs text-gray-500">Invisible</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl min-h-[100px]">
|
||||
<div className="w-8 h-8 mb-2 flex items-center justify-center">
|
||||
<svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-xs text-gray-500">Invisible</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center justify-center p-4 bg-gray-50 rounded-xl min-h-[100px]">
|
||||
<div className="w-8 h-8 mb-2 flex items-center justify-center">
|
||||
<svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-xs text-gray-500">Invisible</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VisibilityAnalysis;
|
||||
|
||||
@@ -49,9 +49,9 @@ const BookOpen = () => {
|
||||
const BookOpenLight = () => {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.89431 5.36141C8.89431 4.58941 8.58763 3.84902 8.04174 3.30313C7.49585 2.75724 6.75547 2.45056 5.98346 2.45056H1.61719V13.3662H6.71117C7.29018 13.3662 7.84547 13.5963 8.25489 14.0057C8.6643 14.4151 8.89431 14.9704 8.89431 15.5494M8.89431 5.36141V15.5494M8.89431 5.36141C8.89431 4.58941 9.20023 3.84902 9.74612 3.30313C10.292 2.75724 11.0324 2.45056 11.8044 2.45056H16.1707V13.3662H11.0767C10.4977 13.3662 9.9424 13.5963 9.53298 14.0057C9.12356 14.4151 8.89431 14.9704 8.89431 15.5494" stroke="#4C60E5" stroke-width="1.35" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M8.89431 5.36141C8.89431 4.58941 8.58763 3.84902 8.04174 3.30313C7.49585 2.75724 6.75547 2.45056 5.98346 2.45056H1.61719V13.3662H6.71117C7.29018 13.3662 7.84547 13.5963 8.25489 14.0057C8.6643 14.4151 8.89431 14.9704 8.89431 15.5494M8.89431 5.36141V15.5494M8.89431 5.36141C8.89431 4.58941 9.20023 3.84902 9.74612 3.30313C10.292 2.75724 11.0324 2.45056 11.8044 2.45056H16.1707V13.3662H11.0767C10.4977 13.3662 9.9424 13.5963 9.53298 14.0057C9.12356 14.4151 8.89431 14.9704 8.89431 15.5494" stroke="#4C60E5" stroke-width="1.35" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
)
|
||||
}
|
||||
@@ -87,12 +87,22 @@ const Header = () => {
|
||||
|
||||
const toggleMenu = () => setIsMenuOpen(!isMenuOpen);
|
||||
const toggleMobileNav = () => setIsMobileNavOpen(!isMobileNavOpen);
|
||||
|
||||
const AnalysisIcon = () => {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.2127 14.5406C15.3937 14.5406 15.5619 14.4433 15.6439 14.2819C16.1591 13.2693 16.4495 12.123 16.4495 10.909C16.4495 6.79475 13.1142 3.45941 8.99987 3.45941C4.88559 3.45941 1.55029 6.79475 1.55029 10.909C1.55029 12.123 1.8407 13.2693 2.35581 14.2819C2.4379 14.4433 2.60602 14.5406 2.78708 14.5406H15.2127Z" stroke="#2B2D3B" stroke-width="1.35" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path d="M9.76179 12.1088C9.31188 12.5587 8.58242 12.5587 8.13251 12.1088C7.6826 11.6589 7.6826 10.9294 8.13251 10.4795C8.43502 10.177 10.7947 8.55389 12.3084 7.52282C12.5809 7.33724 12.904 7.66043 12.7185 7.93288C11.6874 9.44659 10.0643 11.8063 9.76179 12.1088Z" fill="#2B2D3B" />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
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 = () => {
|
||||
<div className="hidden md:flex items-center space-x-4 relative">
|
||||
{/* Add Keyword Button */}
|
||||
|
||||
<button className="flex items-center space-x-2 px-4 py-2 bg-blue-600 text-white rounded-xl font-medium shadow-md hover:bg-blue-700 transition-colors duration-200 ">
|
||||
<Plus size={18} />
|
||||
<span>Add Keywords</span>
|
||||
</button>
|
||||
<button className="flex items-center space-x-2 px-4 py-2 bg-blue-600 text-white rounded-xl font-medium shadow-md hover:bg-blue-700 transition-colors duration-200 ">
|
||||
<Plus size={18} />
|
||||
<span>Add Keywords</span>
|
||||
</button>
|
||||
|
||||
|
||||
<div className="w-0 h-6 outline outline-1 outline-offset-[-0.50px] outline-indigo-200"></div>
|
||||
<div className="w-0 h-6 outline outline-1 outline-offset-[-0.50px] outline-indigo-200"></div>
|
||||
|
||||
{/* Profile Dropdown */}
|
||||
<div className="relative">
|
||||
@@ -248,9 +258,9 @@ const Header = () => {
|
||||
<span>Add Keyword</span>
|
||||
</button> */}
|
||||
|
||||
|
||||
|
||||
<div className="w-0 h-6 outline outline-1 outline-offset-[-0.50px] outline-indigo-200"></div>
|
||||
|
||||
<div className="w-0 h-6 outline outline-1 outline-offset-[-0.50px] outline-indigo-200"></div>
|
||||
|
||||
|
||||
{/* Profile menu */}
|
||||
|
||||
22
src/pages/Analysis.tsx
Normal file
22
src/pages/Analysis.tsx
Normal file
@@ -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 (
|
||||
<ContainerPage>
|
||||
<div className="space-y-8">
|
||||
<AnalysisSearch />
|
||||
<VisibilityAnalysis />
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<SourcesChart />
|
||||
<BecomeTheSource />
|
||||
</div>
|
||||
</div>
|
||||
</ContainerPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default Analysis;
|
||||
المرجع في مشكلة جديدة
حظر مستخدم