Skip to content

Commit 6fb86a7

Browse files
feat: Refactor authentication and repository management components
1 parent e772557 commit 6fb86a7

25 files changed

Lines changed: 1343 additions & 1420 deletions

src/app/app.component.html

Lines changed: 41 additions & 243 deletions
Original file line numberDiff line numberDiff line change
@@ -1,257 +1,55 @@
11
<div class="app-container">
22
<!-- Header -->
3-
<div class="header">
4-
<div class="header-left">
5-
<span class="logo">🔒</span>
6-
<span class="title">GitHub Alerts</span>
7-
</div>
8-
<div class="header-right" *ngIf="authenticated">
9-
<button
10-
class="icon-btn"
11-
(click)="fetchAlerts()"
12-
[disabled]="alertsLoading"
13-
title="Refresh"
14-
>
15-
<span [class.spinning]="alertsLoading">🔄</span>
16-
</button>
17-
<button
18-
class="icon-btn"
19-
[class.active]="currentView === 'repos'"
20-
(click)="showRepos()"
21-
title="Repositories"
22-
>
23-
📦
24-
</button>
25-
<button
26-
class="icon-btn"
27-
[class.active]="currentView === 'settings'"
28-
(click)="showSettings()"
29-
title="Settings"
30-
>
31-
⚙️
32-
</button>
33-
</div>
34-
</div>
3+
<app-header
4+
[authenticated]="authenticated"
5+
[alertsLoading]="alertsLoading"
6+
[currentView]="currentView"
7+
(refresh)="fetchAlerts()"
8+
(viewChange)="onViewChange($event)"
9+
></app-header>
3510

3611
<!-- Not Authenticated -->
37-
<div class="login-panel" *ngIf="!authenticated">
38-
<div class="login-content">
39-
<div class="login-icon">🔐</div>
40-
<h2>Welcome to GitHub Security Alerts</h2>
41-
<p>Enter your GitHub Personal Access Token to monitor security alerts.</p>
42-
<p class="hint">
43-
You need a GitHub Personal Access Token with <strong>repo</strong> and
44-
<strong>read:org</strong> scopes
45-
</p>
46-
<button
47-
class="token-btn"
48-
(click)="openCreateTokenPage()"
49-
title="Open GitHub token creation page"
50-
>
51-
🔑 Create Token on GitHub
52-
</button>
53-
<div class="token-input-group">
54-
<input
55-
type="password"
56-
[(ngModel)]="tokenInput"
57-
placeholder="ghp_xxxxxxxxxxxx"
58-
(keyup.enter)="login()"
59-
[disabled]="authLoading"
60-
/>
61-
<button
62-
class="primary-btn"
63-
(click)="login()"
64-
[disabled]="authLoading || !tokenInput.trim()"
65-
>
66-
<span *ngIf="!authLoading">Connect</span>
67-
<span *ngIf="authLoading">⏳ Connecting...</span>
68-
</button>
69-
</div>
70-
<p class="error-text" *ngIf="error">{{ error }}</p>
71-
</div>
72-
</div>
12+
<app-login-panel
13+
*ngIf="!authenticated"
14+
[authLoading]="authLoading"
15+
[error]="error"
16+
(login)="onLogin($event)"
17+
(openTokenPage)="openCreateTokenPage()"
18+
></app-login-panel>
7319

7420
<!-- Settings View -->
75-
<div
76-
class="settings-panel"
21+
<app-settings-panel
7722
*ngIf="authenticated && currentView === 'settings'"
78-
>
79-
<div class="settings-content">
80-
<div class="user-info">
81-
<span class="user-icon">👤</span>
82-
<span class="username">{{ username }}</span>
83-
</div>
84-
<div class="settings-actions">
85-
<button class="danger-btn" (click)="logout()">🚪 Sign Out</button>
86-
</div>
87-
</div>
88-
</div>
23+
[username]="username"
24+
(logout)="logout()"
25+
></app-settings-panel>
8926

9027
<!-- Repos Selection View -->
91-
<div class="repos-panel" *ngIf="authenticated && currentView === 'repos'">
92-
<div class="repos-header">
93-
<h3>Select Repositories to Monitor</h3>
94-
</div>
95-
96-
<div class="search-box">
97-
<input
98-
type="text"
99-
[(ngModel)]="searchQuery"
100-
placeholder="🔍 Search repositories..."
101-
/>
102-
</div>
103-
104-
<div class="repos-count">{{ selectedCount }} repositories selected</div>
105-
106-
<div class="loading-spinner" *ngIf="ownersLoading">
107-
<span class="spinning">🌀</span> Loading...
108-
</div>
109-
110-
<div class="owners-list" *ngIf="!ownersLoading">
111-
<div class="owner-accordion" *ngFor="let ownerAcc of owners">
112-
<!-- Accordion Header -->
113-
<div
114-
class="accordion-header"
115-
(click)="toggleOwner(ownerAcc)"
116-
[class.expanded]="ownerAcc.expanded"
117-
>
118-
<span class="accordion-icon">{{
119-
ownerAcc.expanded ? "▼" : "▶"
120-
}}</span>
121-
<span class="owner-icon">{{
122-
ownerAcc.owner.is_user ? "👤" : "🏢"
123-
}}</span>
124-
<span class="owner-name">{{ ownerAcc.owner.name }}</span>
125-
<span class="owner-badge" *ngIf="ownerAcc.loaded">
126-
{{ getSelectedCountForOwner(ownerAcc) }}/{{ ownerAcc.repos.length }}
127-
</span>
128-
<span class="owner-badge loading" *ngIf="ownerAcc.loading">
129-
<span class="spinning"></span>
130-
</span>
131-
</div>
132-
133-
<!-- Accordion Content -->
134-
<div class="accordion-content" *ngIf="ownerAcc.expanded">
135-
<div
136-
class="accordion-actions"
137-
*ngIf="ownerAcc.loaded && ownerAcc.repos.length > 0"
138-
>
139-
<button
140-
class="small-btn"
141-
(click)="selectAllForOwner(ownerAcc); $event.stopPropagation()"
142-
>
143-
Select All
144-
</button>
145-
<button
146-
class="small-btn"
147-
(click)="selectNoneForOwner(ownerAcc); $event.stopPropagation()"
148-
>
149-
Select None
150-
</button>
151-
</div>
152-
153-
<div class="loading-spinner small" *ngIf="ownerAcc.loading">
154-
<span class="spinning">🔄</span> Loading repos...
155-
</div>
156-
157-
<div class="repos-list" *ngIf="ownerAcc.loaded">
158-
<div
159-
class="empty-repos"
160-
*ngIf="getFilteredRepos(ownerAcc).length === 0"
161-
>
162-
No repositories found
163-
</div>
164-
<div
165-
class="repo-select-item"
166-
*ngFor="let repo of getFilteredRepos(ownerAcc)"
167-
(click)="toggleRepo(repo); $event.stopPropagation()"
168-
[class.selected]="repo.selected"
169-
>
170-
<div class="checkbox">
171-
<span *ngIf="repo.selected"></span>
172-
</div>
173-
<div class="repo-details">
174-
<span class="repo-name">{{ repo.name }}</span>
175-
</div>
176-
</div>
177-
</div>
178-
</div>
179-
</div>
180-
</div>
181-
182-
<button class="primary-btn" (click)="showAlerts()">
183-
✓ Done - View Alerts
184-
</button>
185-
</div>
186-
187-
<!-- Error Message -->
188-
<div
189-
class="error-banner"
190-
*ngIf="error && authenticated && currentView === 'alerts'"
191-
>
192-
{{ error }}
193-
</div>
28+
<app-repos-panel
29+
*ngIf="authenticated && currentView === 'repos'"
30+
[owners]="owners"
31+
[ownersLoading]="ownersLoading"
32+
[searchQuery]="searchQuery"
33+
(searchQueryChange)="searchQuery = $event"
34+
(toggleOwner)="toggleOwner($event)"
35+
(toggleRepo)="toggleRepo($event)"
36+
(selectAllForOwner)="selectAllForOwner($event)"
37+
(selectNoneForOwner)="selectNoneForOwner($event)"
38+
(done)="showAlerts()"
39+
></app-repos-panel>
19440

19541
<!-- Alerts List View -->
196-
<div class="alerts-list" *ngIf="authenticated && currentView === 'alerts'">
197-
<!-- Loading spinner -->
198-
<div class="loading-spinner" *ngIf="alertsLoading">
199-
<span class="spinning">🔄</span> Loading alerts...
200-
</div>
201-
202-
<!-- No repos selected -->
203-
<div class="empty-state" *ngIf="!alertsLoading && (!alerts || alerts.repos.length === 0)">
204-
<div class="empty-icon">📦</div>
205-
<p>No repositories selected</p>
206-
<button class="primary-btn" (click)="showRepos()">
207-
Select Repositories
208-
</button>
209-
</div>
210-
211-
<!-- Summary -->
212-
<div
213-
class="summary"
214-
*ngIf="alerts && alerts.repos.length > 0"
215-
[class.safe]="alerts.total_alerts === 0"
216-
[class.danger]="alerts.total_alerts > 0"
217-
>
218-
<span class="summary-icon">{{ getAlertIcon() }}</span>
219-
<span class="summary-text" *ngIf="alerts.total_alerts === 0"
220-
>All repositories are secure</span
221-
>
222-
<span class="summary-text" *ngIf="alerts.total_alerts > 0"
223-
>{{ alerts.total_alerts }} security alert(s) found</span
224-
>
225-
</div>
226-
227-
<!-- Repository List -->
228-
<div class="repo-list" *ngIf="alerts && alerts.repos.length > 0">
229-
<div
230-
class="repo-item"
231-
*ngFor="let repo of alerts.repos"
232-
[class.has-alerts]="repo.alerts > 0"
233-
>
234-
<div class="repo-info">
235-
<span class="repo-icon">📦</span>
236-
<span class="repo-name">{{ repo.name.split("/")[1] }}</span>
237-
<span class="repo-org">{{ repo.name.split("/")[0] }}</span>
238-
</div>
239-
<div
240-
class="repo-badge"
241-
[class.safe]="repo.alerts === 0"
242-
[class.danger]="repo.alerts > 0"
243-
>
244-
{{ repo.alerts === 0 ? "✓" : repo.alerts }}
245-
</div>
246-
</div>
247-
</div>
248-
</div>
42+
<app-alerts-list
43+
*ngIf="authenticated && currentView === 'alerts'"
44+
[alerts]="alerts"
45+
[alertsLoading]="alertsLoading"
46+
[error]="error"
47+
(showRepos)="showRepos()"
48+
></app-alerts-list>
24949

25050
<!-- Footer -->
251-
<div class="footer">
252-
<span class="update-time" *ngIf="alerts && authenticated"
253-
>Last update: {{ getLastUpdate() }}</span
254-
>
255-
<span class="version">v1.0.0</span>
256-
</div>
51+
<app-footer
52+
[alerts]="alerts"
53+
[authenticated]="authenticated"
54+
></app-footer>
25755
</div>

0 commit comments

Comments
 (0)