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
+
+
+
+
+
+
+ |
+ ID
+ |
+
+ Username
+ |
+
+ Email
+ |
+
+ Status
+ |
+
+ Roles
+ |
+
+ Created
+ |
+
+ Actions
+ |
+
+
+
+ {mockUsers.map((user) => (
+
+ |
+ {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
+
+
+
+
+
+
+
+
+
+
+
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 (