From a74e4bcf370a3dae09571c216defefb907f10071 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 19 Aug 2025 13:09:07 +0000 Subject: [PATCH 1/4] Initial plan From f4e0a48c8c8613ba3ad5f2eaa15ab5e0390df0e9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 19 Aug 2025 17:41:04 +0000 Subject: [PATCH 2/4] Implement basic authentication infrastructure with login/register forms Co-authored-by: vinod0m <221896197+vinod0m@users.noreply.github.com> --- frontend/App.tsx | 54 ++++++- frontend/components/AdminPanel.tsx | 211 +++++++++++++++++++++++++ frontend/components/AuthGuards.tsx | 75 +++++++++ frontend/components/Dashboard.tsx | 163 ++++++++++++++++++++ frontend/components/HomePage.tsx | 177 +++++++++++++++++++++ frontend/components/LoginForm.tsx | 143 +++++++++++++++++ frontend/components/Navigation.tsx | 86 +++++++++-- frontend/components/RegisterForm.tsx | 172 +++++++++++++++++++++ frontend/stores/authStore.tsx | 221 +++++++++++++++++++++++++++ frontend/types/auth.ts | 37 +++++ 10 files changed, 1326 insertions(+), 13 deletions(-) create mode 100644 frontend/components/AdminPanel.tsx create mode 100644 frontend/components/AuthGuards.tsx create mode 100644 frontend/components/Dashboard.tsx create mode 100644 frontend/components/HomePage.tsx create mode 100644 frontend/components/LoginForm.tsx create mode 100644 frontend/components/RegisterForm.tsx create mode 100644 frontend/stores/authStore.tsx create mode 100644 frontend/types/auth.ts diff --git a/frontend/App.tsx b/frontend/App.tsx index 33e84a8..fb8142a 100644 --- a/frontend/App.tsx +++ b/frontend/App.tsx @@ -1,21 +1,61 @@ import React from 'react'; import { SettingsProvider } from './stores/settingsStore'; +import { AuthProvider, useAuth } from './stores/authStore'; import { Navigation } from './components/Navigation'; import { SettingsPage } from './pages/SettingsPage'; -import { DashboardPage } from './pages/DashboardPage'; +import { HomePage } from './components/HomePage'; +import { LoginForm } from './components/LoginForm'; +import { RegisterForm } from './components/RegisterForm'; +import { Dashboard } from './components/Dashboard'; +import { AdminPanel } from './components/AdminPanel'; import './styles.css'; -function App() { +const AppContent: React.FC = () => { + const { isAuthenticated, isLoading } = useAuth(); + // Simple routing based on hash const currentHash = window.location.hash.slice(1) || '/'; const renderPage = () => { + if (isLoading) { + return ( +
+
+
+ ); + } + + // Public routes + if (currentHash === '/login') { + return ; + } + + if (currentHash === '/register') { + return ; + } + + // Protected routes + if (!isAuthenticated) { + if (currentHash === '/') { + return ; + } + // Redirect to login for protected routes + window.location.hash = '/login'; + return ; + } + + // Authenticated routes switch (currentHash) { + case '/dashboard': + return ; + case '/admin': + return ; case '/settings': return ; case '/': default: - return ; + // For authenticated users, default to dashboard + return ; } }; @@ -38,6 +78,14 @@ function App() { ); +}; + +function App() { + return ( + + + + ); } export default App; \ No newline at end of file diff --git a/frontend/components/AdminPanel.tsx b/frontend/components/AdminPanel.tsx new file mode 100644 index 0000000..12bf7c1 --- /dev/null +++ b/frontend/components/AdminPanel.tsx @@ -0,0 +1,211 @@ +import React from 'react'; +import { RequireAdmin } from './AuthGuards'; + +// Mock data for admin panel +const mockUsers = [ + { + id: 1, + username: 'admin', + email: 'admin@sdlccore.com', + status: 'Active', + roles: ['admin'], + created: '08/15/2025' + }, + { + id: 2, + username: 'developer1', + email: 'dev@sdlccore.com', + status: 'Active', + roles: ['developer'], + created: '08/16/2025' + }, + { + id: 3, + username: 'analyst1', + email: 'analyst@sdlccore.com', + status: 'Active', + roles: ['analyst'], + created: '08/17/2025' + } +]; + +const mockRoles = [ + { + id: 1, + name: 'admin', + description: 'Full system administrator access' + }, + { + id: 2, + name: 'user', + description: 'Standard user access' + }, + { + id: 3, + name: 'moderator', + description: 'Content moderation access' + }, + { + id: 4, + name: 'analyst', + description: 'Analytics and reporting access' + }, + { + id: 5, + name: 'developer', + description: 'Development and deployment access' + } +]; + +export const AdminPanel: React.FC = () => { + return ( + +
+
Access Denied
+
You need administrator privileges to access this panel.
+
+ + }> +
+
+

Admin Panel

+

Manage users and roles in the system.

+
+ + {/* Users Management */} +
+
+

Users Management

+
+ +
+ + + + + + + + + + + + + + {mockUsers.map((user) => ( + + + + + + + + + + ))} + +
+ ID + + Username + + Email + + Status + + Roles + + Created + + Actions +
+ {user.id} + + {user.username} + + {user.email} + + + {user.status} + + +
+ {user.roles.map((role, index) => ( + + {role} + + ))} +
+
+ {user.created} + + + +
+
+
+ + {/* Roles Management */} +
+
+

Roles

+
+ +
+
+ {mockRoles.map((role) => ( +
+
+

+ {role.name} +

+ + {role.name} + +
+

+ {role.description} +

+
+ + +
+
+ ))} +
+
+
+
+
+ ); +}; \ No newline at end of file diff --git a/frontend/components/AuthGuards.tsx b/frontend/components/AuthGuards.tsx new file mode 100644 index 0000000..73622a7 --- /dev/null +++ b/frontend/components/AuthGuards.tsx @@ -0,0 +1,75 @@ +import React, { ReactNode } from 'react'; +import { useAuth } from '../stores/authStore'; +import { UserRole } from '../types/auth'; + +interface RequireAuthProps { + children: ReactNode; + fallback?: ReactNode; +} + +export const RequireAuth: React.FC = ({ + children, + fallback =
Please log in to access this content.
+}) => { + const { isAuthenticated, isLoading } = useAuth(); + + if (isLoading) { + return
+
+
; + } + + if (!isAuthenticated) { + return <>{fallback}; + } + + return <>{children}; +}; + +interface RequireRoleProps { + children: ReactNode; + role: UserRole | UserRole[]; + fallback?: ReactNode; +} + +export const RequireRole: React.FC = ({ + children, + role, + fallback =
You don't have permission to access this content.
+}) => { + const { hasRole, hasAnyRole } = useAuth(); + + const hasPermission = Array.isArray(role) + ? hasAnyRole(role) + : hasRole(role); + + if (!hasPermission) { + return <>{fallback}; + } + + return <>{children}; +}; + +export const RequireAdmin: React.FC = ({ children, fallback }) => ( + + {children} + +); + +export const RequireModerator: React.FC = ({ children, fallback }) => ( + + {children} + +); + +export const RequireAnalyst: React.FC = ({ children, fallback }) => ( + + {children} + +); + +export const RequireDeveloper: React.FC = ({ children, fallback }) => ( + + {children} + +); \ No newline at end of file diff --git a/frontend/components/Dashboard.tsx b/frontend/components/Dashboard.tsx new file mode 100644 index 0000000..b335e55 --- /dev/null +++ b/frontend/components/Dashboard.tsx @@ -0,0 +1,163 @@ +import React from 'react'; +import { useAuth } from '../stores/authStore'; +import { Role } from '../types/auth'; + +const RoleBadge: React.FC<{ role: Role }> = ({ role }) => { + const getColorClass = (roleName: string) => { + switch (roleName) { + case 'admin': + return 'bg-red-100 text-red-800'; + case 'developer': + return 'bg-blue-100 text-blue-800'; + case 'analyst': + return 'bg-green-100 text-green-800'; + case 'moderator': + return 'bg-yellow-100 text-yellow-800'; + case 'user': + default: + return 'bg-gray-100 text-gray-800'; + } + }; + + return ( + + {role.name} + + ); +}; + +export const Dashboard: React.FC = () => { + const { user, logout, isLoading } = useAuth(); + + if (!user) { + return null; + } + + const handleLogout = async () => { + try { + await logout(); + } catch (error) { + console.error('Logout failed:', error); + } + }; + + const handleRefreshProfile = () => { + window.location.reload(); + }; + + return ( +
+
+
+ + + + Logged in successfully! 👋 +
+
+ +
+

Dashboard

+

Welcome to your personal dashboard, {user.username}!

+
+ +
+
+

Profile Information

+
+ +
+
+
+
Username:
+
{user.username}
+
+ +
+
Email:
+
{user.email}
+
+ +
+
Account Status:
+
+ + {user.isActive ? 'Active' : 'Inactive'} + +
+
+ +
+
Member Since:
+
{user.memberSince}
+
+ +
+
Last Login:
+
{user.lastLogin}
+
+ +
+
Roles:
+
+
+ {user.roles.map((role) => ( + + ))} +
+
+
+
+
+
+ +
+
+

Quick Actions

+
+ +
+
+ + Admin Panel + + + + + +
+
+
+ +
+
+

System Info

+
+ +
+
+
SDLC Core Frontend Infrastructure
+
Role-based Authentication System
+
+
+
+
+ ); +}; \ No newline at end of file diff --git a/frontend/components/HomePage.tsx b/frontend/components/HomePage.tsx new file mode 100644 index 0000000..aecd0f1 --- /dev/null +++ b/frontend/components/HomePage.tsx @@ -0,0 +1,177 @@ +import React from 'react'; + +export const HomePage: React.FC = () => { + return ( +
+ {/* Hero Section */} +
+
+
+

+ Welcome to SDLC Core +

+

+ A comprehensive software development lifecycle management platform with role-based authentication. +

+ +
+
+
+ + {/* Features Section */} +
+
+
+

+ Key Features +

+

+ Everything you need for modern software development lifecycle management +

+
+ +
+ {/* Role-Based Access */} +
+
+ + + +
+

Role-Based Access

+

+ Secure authentication system with granular role-based permissions. +

+
+ + {/* LLM Integration */} +
+
+ + + +
+

LLM Integration

+

+ Advanced AI capabilities with multiple LLM provider support. +

+
+ + {/* Analytics & Monitoring */} +
+
+ + + +
+

Analytics & Monitoring

+

+ Comprehensive analytics and monitoring for development workflows. +

+
+
+
+
+ + {/* Role-Based Access Details */} +
+
+
+

Role-Based Access

+

+ Secure authentication system with granular role-based permissions. +

+ +
+
+
+ A +
+

Admin

+

Full system access

+
+ +
+
+ D +
+

Developer

+

Code deployment

+
+ +
+
+ A +
+

Analyst

+

Data analysis

+
+ +
+
+ M +
+

Moderator

+

Content management

+
+ +
+
+ U +
+

User

+

Basic access

+
+
+
+
+
+ + {/* LLM Integration Details */} +
+
+
+

LLM Integration

+

+ Advanced AI capabilities with multiple LLM provider support. +

+ +
+
+

OpenAI GPT

+

Industry-leading language models

+
+
+

Anthropic Claude

+

Safe and helpful AI assistant

+
+
+

Custom Models

+

Support for specialized models

+
+
+
+
+
+ + {/* Analytics & Monitoring Details */} +
+
+
+

Analytics & Monitoring

+

+ Comprehensive analytics and monitoring for development workflows. +

+
+
+
+
+ ); +}; \ No newline at end of file diff --git a/frontend/components/LoginForm.tsx b/frontend/components/LoginForm.tsx new file mode 100644 index 0000000..5365855 --- /dev/null +++ b/frontend/components/LoginForm.tsx @@ -0,0 +1,143 @@ +import React, { useState } from 'react'; +import { useAuth } from '../stores/authStore'; +import { LoginCredentials } from '../types/auth'; + +export const LoginForm: React.FC = () => { + const { login, isLoading, error, clearError } = useAuth(); + const [credentials, setCredentials] = useState({ + username: '', + password: '', + rememberMe: false + }); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + clearError(); + + try { + await login(credentials); + // Navigation will be handled by the app based on auth state + } catch (error) { + // Error is handled by the auth store + } + }; + + const handleChange = (e: React.ChangeEvent) => { + const { name, value, type, checked } = e.target; + setCredentials(prev => ({ + ...prev, + [name]: type === 'checkbox' ? checked : value + })); + }; + + return ( +
+
+

+ Sign In +

+
+ +
+
+
+ {error && ( +
+ {error} +
+ )} + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ +
+
+ +
+
+ Don't have an account? + + Register here + +
+
+ +
+
Demo accounts:
+
Admin: admin / admin123
+
User: user / user123
+
+
+
+ +
+ © 2024 SDLC Core. All rights reserved. +
+
+ ); +}; \ No newline at end of file diff --git a/frontend/components/Navigation.tsx b/frontend/components/Navigation.tsx index 74a33bc..365d92d 100644 --- a/frontend/components/Navigation.tsx +++ b/frontend/components/Navigation.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { useState } from 'react'; +import { useAuth } from '../stores/authStore'; interface NavItemProps { href: string; @@ -22,7 +23,19 @@ const NavItem: React.FC = ({ href, children, isActive = false }) = }; export const Navigation: React.FC = () => { + const { user, isAuthenticated, logout, hasRole } = useAuth(); + const [isUserMenuOpen, setIsUserMenuOpen] = useState(false); const currentHash = window.location.hash.slice(1) || '/'; + + const handleLogout = async () => { + try { + await logout(); + setIsUserMenuOpen(false); + window.location.hash = '/'; + } catch (error) { + console.error('Logout failed:', error); + } + }; return (