diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b41d5c6..ee32ba0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17,6 +17,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-hot-toast": "^2.5.2", + "react-router-dom": "^7.5.0", "recharts": "^2.15.1", "tailwind-merge": "^3.0.2" }, @@ -1264,6 +1265,12 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, "node_modules/@types/d3-array": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", @@ -1989,6 +1996,15 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4559,6 +4575,46 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.0.tgz", + "integrity": "sha512-estOHrRlDMKdlQa6Mj32gIks4J+AxNsYoE0DbTTxiMy2mPzZuWSDU+N85/r1IlNR7kGfznF3VCUlvc5IUO+B9g==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.5.0.tgz", + "integrity": "sha512-fFhGFCULy4vIseTtH5PNcY/VvDJK5gvOWcwJVHQp8JQcWVr85ENhJ3UpuF/zP1tQOIFYNRJHzXtyhU1Bdgw0RA==", + "license": "MIT", + "dependencies": { + "react-router": "7.5.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/react-smooth": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", @@ -5083,6 +5139,12 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==", + "license": "ISC" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index d827390..65980cc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-hot-toast": "^2.5.2", + "react-router-dom": "^7.5.0", "recharts": "^2.15.1", "tailwind-merge": "^3.0.2" }, diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 65b703f..4e2a127 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,9 +1,10 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; +import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; import { AnimatePresence } from 'framer-motion'; - import Sidebar from './components/layout/Sidebar'; import Dashboard from './components/dashboard/Dashboard'; + import BotIntegrationPage from './components/integration/BotIntegrationPage'; import ContributorsPage from './components/contributors/ContributorsPage'; import PullRequestsPage from './components/pages/PullRequestsPage'; @@ -42,26 +43,48 @@ function App() { }; return ( -
- - {activePage !== 'landing' && ( - - )} - -
- -
- - {renderPage()} - -
-
-
+ +
+ + + ) : ( + + ) + } + /> + + +
+
+ {renderPage()} +
+
+
+ ) : ( + + ) + } + /> + + +
); } diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx index b1f4b01..9976dc4 100644 --- a/frontend/src/components/layout/Sidebar.tsx +++ b/frontend/src/components/layout/Sidebar.tsx @@ -9,7 +9,8 @@ import { GitPullRequest, MessageCircleQuestion, Menu, - Settings + Settings, + User } from 'lucide-react'; interface SidebarProps { @@ -37,6 +38,7 @@ const Sidebar: React.FC = ({ isOpen, setIsOpen, activePage, setAct { icon: , label: 'Pull Requests', id: 'prs' }, { icon: , label: 'Support', id: 'support' }, { icon: , label: 'Settings', id: 'settings' }, + { icon: , label: 'Profile', id: 'profile' }, ].map((item) => ( + + + + {isLoading ? ( + + + + ) : ( + <> + + Sign In + + )} + + +

+ Don't have an account?{' '} + +

+ + + + ); +} diff --git a/frontend/src/components/pages/ProfilePage.tsx b/frontend/src/components/pages/ProfilePage.tsx new file mode 100644 index 0000000..d9b3b7e --- /dev/null +++ b/frontend/src/components/pages/ProfilePage.tsx @@ -0,0 +1,209 @@ +import { useState } from 'react'; +import { motion } from 'framer-motion'; +import { toast } from 'react-hot-toast'; +import { User, Mail, Building, Globe, Github, Twitter, Edit, Camera, Save } from 'lucide-react'; + +const ProfilePage = () => { + const [isEditing, setIsEditing] = useState(false); + const [profile, setProfile] = useState({ + name: 'Sarah Chen', + role: 'Core Maintainer', + company: 'TechCorp Inc.', + email: 'sarah.chen@example.com', + website: 'https://sarahchen.dev', + github: '@sarahchen', + twitter: '@sarahchen_dev', + bio: 'Open source enthusiast and community builder. Working on developer tools and AI-powered solutions.', + }); + + const handleSave = () => { + setIsEditing(false); + toast.success('Profile updated successfully!'); + }; + + return ( + +
+

Profile

+ setIsEditing(!isEditing)} + className="px-4 py-2 bg-green-500 hover:bg-green-600 rounded-lg transition-colors flex items-center" + > + {isEditing ? ( + <> + + Save Changes + + ) : ( + <> + + Edit Profile + + )} + +
+ +
+
+ + + +
+ +
+
+
+ Profile + + + +
+
+ +
+
+
+ +
+ + setProfile({ ...profile, name: e.target.value })} + disabled={!isEditing} + className="bg-transparent text-white focus:outline-none disabled:opacity-50" + /> +
+
+ +
+ +
+ + setProfile({ ...profile, email: e.target.value })} + disabled={!isEditing} + className="bg-transparent text-white focus:outline-none disabled:opacity-50" + /> +
+
+ +
+ +
+ + setProfile({ ...profile, company: e.target.value })} + disabled={!isEditing} + className="bg-transparent text-white focus:outline-none disabled:opacity-50" + /> +
+
+
+ +
+
+ +
+ + setProfile({ ...profile, website: e.target.value })} + disabled={!isEditing} + className="bg-transparent text-white focus:outline-none disabled:opacity-50" + /> +
+
+ +
+ +
+ + setProfile({ ...profile, github: e.target.value })} + disabled={!isEditing} + className="bg-transparent text-white focus:outline-none disabled:opacity-50" + /> +
+
+ +
+ +
+ + setProfile({ ...profile, twitter: e.target.value })} + disabled={!isEditing} + className="bg-transparent text-white focus:outline-none disabled:opacity-50" + /> +
+
+
+
+ +
+ +