Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,20 @@ src/
### ⚑ Quick Start

1. **Clone the repository**

```bash
git clone https://github.com/guibranco/gstraccini-bot-portal.git
cd gstraccini-bot-portal
```

2. **Install dependencies**

```bash
npm install
```

3. **Start development server**

```bash
npm run dev
```
Expand All @@ -165,14 +168,14 @@ src/

### πŸ› οΈ Available Scripts

| Command | Description |
|---------|-------------|
| `npm run dev` | Start development server with hot reload |
| `npm run build` | Build production-ready application |
| `npm run preview` | Preview production build locally |
| `npm run lint` | Run ESLint for code quality checks |
| `npm run test` | Run test suite with Vitest |
| `npm run test:coverage` | Run tests with coverage report |
| Command | Description |
| ----------------------- | ---------------------------------------- |
| `npm run dev` | Start development server with hot reload |
| `npm run build` | Build production-ready application |
| `npm run preview` | Preview production build locally |
| `npm run lint` | Run ESLint for code quality checks |
| `npm run test` | Run test suite with Vitest |
| `npm run test:coverage` | Run tests with coverage report |

---

Expand Down Expand Up @@ -209,30 +212,35 @@ src/
## 🌟 Features

### 🎯 Dashboard & Analytics

- **Real-time Statistics** - Live metrics for repositories, PRs, and issues
- **Activity Timeline** - Chronological view of all repository activities
- **Performance Insights** - Detailed analytics on workflow efficiency
- **Custom Widgets** - Configurable dashboard components

### πŸ” Security & Authentication

- **GitHub OAuth Integration** - Secure authentication via GitHub
- **Multi-Factor Authentication** - FIDO2, TOTP, and recovery codes support
- **Session Management** - Secure session handling and automatic expiration
- **Permission Controls** - Granular access control for repositories

### πŸ”§ Repository Management

- **Branch Protection** - Configure and manage branch protection rules
- **Workflow Automation** - Set up and monitor GitHub Actions workflows
- **Integration Hub** - Connect with SonarCloud, Codacy, Snyk, and more
- **Release Management** - Track and manage repository releases

### πŸ“Š Pull Request & Issue Tracking

- **Advanced Filtering** - Filter by status, labels, assignees, and more
- **Bulk Operations** - Perform actions on multiple items simultaneously
- **Timeline Visualization** - Visual representation of PR/issue lifecycle
- **Automated Workflows** - Set up automated responses and actions

### πŸ”” Notifications & Alerts

- **Real-time Notifications** - Instant updates on important events
- **Custom Filters** - Configure notification preferences
- **Priority Levels** - Categorize notifications by importance
Expand All @@ -253,6 +261,7 @@ src/
### 🎭 Dark Mode Support

The application features a comprehensive dark mode implementation with:

- **System Preference Detection** - Automatically adapts to user's system theme
- **Manual Toggle** - Users can override system preference
- **Persistent Settings** - Theme preference saved in localStorage
Expand Down Expand Up @@ -297,7 +306,7 @@ The project uses Vite with SWC for optimal performance:
export default defineConfig({
plugins: [react()],
optimizeDeps: {
exclude: ['lucide-react'],
exclude: ["lucide-react"],
},
});
```
Expand All @@ -322,6 +331,7 @@ npm run test:coverage
```

Coverage reports are generated in the `coverage/` directory with:

- **HTML Reports** - Interactive coverage visualization
- **JSON Reports** - Machine-readable coverage data
- **LCOV Reports** - Integration with external tools
Expand Down Expand Up @@ -360,6 +370,7 @@ CMD ["nginx", "-g", "daemon off;"]
### ☁️ Deployment Platforms

The application is optimized for deployment on:

- **Vercel** - Zero-configuration deployment
- **Netlify** - Continuous deployment from Git
- **AWS S3 + CloudFront** - Scalable static hosting
Expand Down Expand Up @@ -420,4 +431,4 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE)

[⭐ Star this repository](https://github.com/guibranco/gstraccini-bot-portal) if you find it helpful!

</div>
</div>
24 changes: 12 additions & 12 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import tseslint from 'typescript-eslint';
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";

export default tseslint.config(
{ ignores: ['dist'] },
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
}
},
);
56 changes: 32 additions & 24 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { AuthProvider } from './context/AuthContext';
import { PublicLayout } from './layouts/PublicLayout';
import { AuthenticatedLayout } from './layouts/AuthenticatedLayout';
import { Landing } from './pages/Landing';
import Auth from './pages/Auth';
import ForgotPassword from './pages/ForgotPassword';
import Privacy from './pages/Privacy';
import Security from './pages/Security';
import Status from './pages/Status';
import Terms from './pages/Terms';
import { Dashboard } from './pages/Dashboard';
import { Repositories } from './pages/Repositories';
import { RepositoryDetail } from './pages/RepositoryDetail';
import { Issues } from './pages/Issues';
import { PullRequests } from './pages/PullRequests';
import { PullRequestDetail } from './pages/PullRequestDetail';
import { Notifications } from './pages/Notifications';
import { Account } from './pages/Account';
import { Settings } from './pages/Settings';
import { Integrations } from './pages/Integrations';
import {
BrowserRouter as Router,
Routes,
Route,
Navigate,
} from "react-router-dom";
import { AuthProvider } from "./context/AuthContext";
import { PublicLayout } from "./layouts/PublicLayout";
import { AuthenticatedLayout } from "./layouts/AuthenticatedLayout";
import { Landing } from "./pages/Landing";
import Auth from "./pages/Auth";
import ForgotPassword from "./pages/ForgotPassword";
import Privacy from "./pages/Privacy";
import Security from "./pages/Security";
import Status from "./pages/Status";
import Terms from "./pages/Terms";
import { Dashboard } from "./pages/Dashboard";
import { Repositories } from "./pages/Repositories";
import { RepositoryDetail } from "./pages/RepositoryDetail";
import { Issues } from "./pages/Issues";
import { PullRequests } from "./pages/PullRequests";
import { PullRequestDetail } from "./pages/PullRequestDetail";
import { Notifications } from "./pages/Notifications";
import { Account } from "./pages/Account";
import { Settings } from "./pages/Settings";
import { Integrations } from "./pages/Integrations";

function App() {
return (
Expand All @@ -35,12 +40,15 @@ function App() {
<Route path="status" element={<Status />} />
<Route path="terms" element={<Terms />} />
</Route>

{/* Authenticated Routes - Dashboard Area */}
<Route path="/dashboard" element={<AuthenticatedLayout />}>
<Route index element={<Dashboard />} />
<Route path="repositories" element={<Repositories />} />
<Route path="repositories/:org/:repo" element={<RepositoryDetail />} />
<Route
path="repositories/:org/:repo"
element={<RepositoryDetail />}
/>
<Route path="issues" element={<Issues />} />
<Route path="pull-requests" element={<PullRequests />} />
<Route path="pull-requests/:id" element={<PullRequestDetail />} />
Expand All @@ -49,7 +57,7 @@ function App() {
<Route path="settings" element={<Settings />} />
<Route path="integrations" element={<Integrations />} />
</Route>

{/* Catch all route - redirect to landing */}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
Expand Down
45 changes: 28 additions & 17 deletions src/components/ActivityList.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
import { Activity } from '../types';
import { GitPullRequest, GitMerge, XCircle, GitCommit, GitPullRequestDraft } from 'lucide-react';
import { Link } from 'react-router-dom';
import { Activity } from "../types";
import {
GitPullRequest,
GitMerge,
XCircle,
GitCommit,
GitPullRequestDraft,
} from "lucide-react";
import { Link } from "react-router-dom";

interface ActivityListProps {
activities: Activity[];
}

const getActivityIcon = (type: Activity['type']) => {
const getActivityIcon = (type: Activity["type"]) => {
switch (type) {
case 'pr_created':
case "pr_created":
return <GitPullRequest className="w-5 h-5 text-blue-500" />;
case 'pr_merged':
case "pr_merged":
return <GitMerge className="w-5 h-5 text-purple-500" />;
case 'issue_closed':
case "issue_closed":
return <XCircle className="w-5 h-5 text-green-500" />;
case 'commits_analyzed':
case "commits_analyzed":
return <GitCommit className="w-5 h-5 text-orange-500" />;
case 'pr_opened':
case "pr_opened":
return <GitPullRequestDraft className="w-5 h-5 text-blue-500" />;
}
};

export function ActivityList({ activities }: ActivityListProps) {
return (
<div className="bg-white rounded-xl shadow-lg p-6">
<h3 className="text-xl font-semibold text-gray-800 mb-4">Recent Activities</h3>
<h3 className="text-xl font-semibold text-gray-800 mb-4">
Recent Activities
</h3>
<div className="space-y-4">
{activities.map((activity) => (
<div key={activity.id} className="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg">
<div
key={activity.id}
className="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg"
>
{getActivityIcon(activity.type)}
<div className="flex-1">
<div className="flex items-center space-x-2">
Expand All @@ -54,11 +65,11 @@ export function ActivityList({ activities }: ActivityListProps) {
{activity.repository}
</Link>
<span className="mx-2">β€’</span>
{new Date(activity.timestamp).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
{new Date(activity.timestamp).toLocaleDateString("en-US", {
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
})}
</p>
</div>
Expand All @@ -67,4 +78,4 @@ export function ActivityList({ activities }: ActivityListProps) {
</div>
</div>
);
}
}
Loading
Loading