appclean 1.8.0 โ 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GUI_IMPLEMENTATION_STATUS.md +143 -0
- package/MD_Files/INDEX.md +51 -0
- package/MD_Files/PUBLICATION_SUCCESS_REPORT.md +227 -0
- package/PHASE2_COMPLETION.md +281 -0
- package/PHASE3_COMPLETION.md +364 -0
- package/README.md +446 -376
- package/assets/logo.svg +34 -0
- package/dist/core/appUpdateChecker.js +12 -16
- package/dist/core/appUpdateChecker.js.map +1 -1
- package/dist/core/detector.js +14 -18
- package/dist/core/detector.js.map +1 -1
- package/dist/core/duplicateFileFinder.js +12 -19
- package/dist/core/duplicateFileFinder.js.map +1 -1
- package/dist/core/orphanedDependencyDetector.js +19 -26
- package/dist/core/orphanedDependencyDetector.js.map +1 -1
- package/dist/core/performanceOptimizer.js +6 -10
- package/dist/core/performanceOptimizer.js.map +1 -1
- package/dist/core/permissionHandler.js +21 -25
- package/dist/core/permissionHandler.js.map +1 -1
- package/dist/core/pluginSystem.js +9 -13
- package/dist/core/pluginSystem.js.map +1 -1
- package/dist/core/removalRecorder.js +12 -19
- package/dist/core/removalRecorder.js.map +1 -1
- package/dist/core/remover.js +59 -66
- package/dist/core/remover.js.map +1 -1
- package/dist/core/reportGenerator.d.ts +1 -1
- package/dist/core/reportGenerator.d.ts.map +1 -1
- package/dist/core/reportGenerator.js +27 -34
- package/dist/core/reportGenerator.js.map +1 -1
- package/dist/core/scheduledCleanup.js +23 -30
- package/dist/core/scheduledCleanup.js.map +1 -1
- package/dist/core/serviceFileDetector.js +24 -31
- package/dist/core/serviceFileDetector.js.map +1 -1
- package/dist/core/verificationModule.js +10 -14
- package/dist/core/verificationModule.js.map +1 -1
- package/dist/index.js +190 -90
- package/dist/index.js.map +1 -1
- package/dist/managers/brewManager.d.ts.map +1 -1
- package/dist/managers/brewManager.js +35 -41
- package/dist/managers/brewManager.js.map +1 -1
- package/dist/managers/customManager.d.ts +2 -1
- package/dist/managers/customManager.d.ts.map +1 -1
- package/dist/managers/customManager.js +79 -53
- package/dist/managers/customManager.js.map +1 -1
- package/dist/managers/linuxManager.js +29 -36
- package/dist/managers/linuxManager.js.map +1 -1
- package/dist/managers/npmManager.js +27 -34
- package/dist/managers/npmManager.js.map +1 -1
- package/dist/types/index.js +1 -2
- package/dist/ui/client/api/client.d.ts +24 -0
- package/dist/ui/client/api/client.d.ts.map +1 -0
- package/dist/ui/client/api/client.js +96 -0
- package/dist/ui/client/api/client.js.map +1 -0
- package/dist/ui/client/app.d.ts +7 -0
- package/dist/ui/client/app.d.ts.map +1 -0
- package/dist/ui/client/app.js +71 -0
- package/dist/ui/client/app.js.map +1 -0
- package/dist/ui/client/index.html +107 -0
- package/dist/ui/client/pages/appDetails.d.ts +8 -0
- package/dist/ui/client/pages/appDetails.d.ts.map +1 -0
- package/dist/ui/client/pages/appDetails.js +287 -0
- package/dist/ui/client/pages/appDetails.js.map +1 -0
- package/dist/ui/client/pages/appSearch.d.ts +2 -0
- package/dist/ui/client/pages/appSearch.d.ts.map +1 -0
- package/dist/ui/client/pages/appSearch.js +210 -0
- package/dist/ui/client/pages/appSearch.js.map +1 -0
- package/dist/ui/client/pages/dashboard.d.ts +2 -0
- package/dist/ui/client/pages/dashboard.d.ts.map +1 -0
- package/dist/ui/client/pages/dashboard.js +154 -0
- package/dist/ui/client/pages/dashboard.js.map +1 -0
- package/dist/ui/client/pages/settings.d.ts +7 -0
- package/dist/ui/client/pages/settings.d.ts.map +1 -0
- package/dist/ui/client/pages/settings.js +279 -0
- package/dist/ui/client/pages/settings.js.map +1 -0
- package/dist/ui/client/state/appStore.d.ts +38 -0
- package/dist/ui/client/state/appStore.d.ts.map +1 -0
- package/dist/ui/client/state/appStore.js +121 -0
- package/dist/ui/client/state/appStore.js.map +1 -0
- package/dist/ui/client/state/dashboardStore.d.ts +31 -0
- package/dist/ui/client/state/dashboardStore.d.ts.map +1 -0
- package/dist/ui/client/state/dashboardStore.js +70 -0
- package/dist/ui/client/state/dashboardStore.js.map +1 -0
- package/dist/ui/client/state/uiStore.d.ts +43 -0
- package/dist/ui/client/state/uiStore.d.ts.map +1 -0
- package/dist/ui/client/state/uiStore.js +109 -0
- package/dist/ui/client/state/uiStore.js.map +1 -0
- package/dist/ui/client/styles/animations.css +327 -0
- package/dist/ui/client/styles/base.css +214 -0
- package/dist/ui/client/styles/components.css +400 -0
- package/dist/ui/client/styles/layout.css +224 -0
- package/dist/ui/client/styles/variables.css +140 -0
- package/dist/ui/client/utils/events.d.ts +19 -0
- package/dist/ui/client/utils/events.d.ts.map +1 -0
- package/dist/ui/client/utils/events.js +54 -0
- package/dist/ui/client/utils/events.js.map +1 -0
- package/dist/ui/client/utils/formatting.d.ts +11 -0
- package/dist/ui/client/utils/formatting.d.ts.map +1 -0
- package/dist/ui/client/utils/formatting.js +104 -0
- package/dist/ui/client/utils/formatting.js.map +1 -0
- package/dist/ui/client/utils/router.d.ts +25 -0
- package/dist/ui/client/utils/router.d.ts.map +1 -0
- package/dist/ui/client/utils/router.js +90 -0
- package/dist/ui/client/utils/router.js.map +1 -0
- package/dist/ui/guiServer.d.ts +8 -1
- package/dist/ui/guiServer.d.ts.map +1 -1
- package/dist/ui/guiServer.js +148 -110
- package/dist/ui/guiServer.js.map +1 -1
- package/dist/ui/menu.js +18 -27
- package/dist/ui/menu.js.map +1 -1
- package/dist/ui/prompts.js +34 -47
- package/dist/ui/prompts.js.map +1 -1
- package/dist/ui/server/middleware/errorHandler.d.ts +19 -0
- package/dist/ui/server/middleware/errorHandler.d.ts.map +1 -0
- package/dist/ui/server/middleware/errorHandler.js +100 -0
- package/dist/ui/server/middleware/errorHandler.js.map +1 -0
- package/dist/ui/server/routes/apps.d.ts +8 -0
- package/dist/ui/server/routes/apps.d.ts.map +1 -0
- package/dist/ui/server/routes/apps.js +74 -0
- package/dist/ui/server/routes/apps.js.map +1 -0
- package/dist/ui/server/routes/dashboard.d.ts +4 -0
- package/dist/ui/server/routes/dashboard.d.ts.map +1 -0
- package/dist/ui/server/routes/dashboard.js +57 -0
- package/dist/ui/server/routes/dashboard.js.map +1 -0
- package/dist/ui/server/routes/settings.d.ts +6 -0
- package/dist/ui/server/routes/settings.d.ts.map +1 -0
- package/dist/ui/server/routes/settings.js +31 -0
- package/dist/ui/server/routes/settings.js.map +1 -0
- package/dist/ui/server/services/appService.d.ts +45 -0
- package/dist/ui/server/services/appService.d.ts.map +1 -0
- package/dist/ui/server/services/appService.js +114 -0
- package/dist/ui/server/services/appService.js.map +1 -0
- package/dist/ui/server/services/removalService.d.ts +24 -0
- package/dist/ui/server/services/removalService.d.ts.map +1 -0
- package/dist/ui/server/services/removalService.js +83 -0
- package/dist/ui/server/services/removalService.js.map +1 -0
- package/dist/utils/filesystem.js +32 -49
- package/dist/utils/filesystem.js.map +1 -1
- package/dist/utils/logger.js +9 -18
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/platform.js +10 -22
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/upgrade.d.ts +22 -0
- package/dist/utils/upgrade.d.ts.map +1 -0
- package/dist/utils/upgrade.js +94 -0
- package/dist/utils/upgrade.js.map +1 -0
- package/package.json +4 -2
- package/src/core/appUpdateChecker.ts +1 -1
- package/src/core/detector.ts +6 -6
- package/src/core/duplicateFileFinder.ts +1 -1
- package/src/core/orphanedDependencyDetector.ts +2 -2
- package/src/core/performanceOptimizer.ts +1 -1
- package/src/core/permissionHandler.ts +2 -2
- package/src/core/pluginSystem.ts +1 -1
- package/src/core/removalRecorder.ts +2 -2
- package/src/core/remover.ts +11 -11
- package/src/core/reportGenerator.ts +2 -2
- package/src/core/scheduledCleanup.ts +2 -2
- package/src/core/serviceFileDetector.ts +2 -2
- package/src/core/verificationModule.ts +2 -2
- package/src/index.ts +133 -6
- package/src/managers/brewManager.ts +11 -9
- package/src/managers/customManager.ts +71 -30
- package/src/managers/linuxManager.ts +3 -3
- package/src/managers/npmManager.ts +3 -3
- package/src/ui/client/api/client.ts +163 -0
- package/src/ui/client/app.ts +121 -0
- package/src/ui/client/index.html +107 -0
- package/src/ui/client/pages/appDetails.ts +356 -0
- package/src/ui/client/pages/appSearch.ts +270 -0
- package/src/ui/client/pages/dashboard.ts +189 -0
- package/src/ui/client/pages/settings.ts +342 -0
- package/src/ui/client/state/appStore.ts +169 -0
- package/src/ui/client/state/dashboardStore.ts +113 -0
- package/src/ui/client/state/uiStore.ts +166 -0
- package/src/ui/client/styles/animations.css +327 -0
- package/src/ui/client/styles/base.css +214 -0
- package/src/ui/client/styles/components.css +400 -0
- package/src/ui/client/styles/layout.css +224 -0
- package/src/ui/client/styles/variables.css +140 -0
- package/src/ui/client/utils/events.ts +74 -0
- package/src/ui/client/utils/formatting.ts +157 -0
- package/src/ui/client/utils/router.ts +161 -0
- package/src/ui/guiServer.ts +206 -105
- package/src/ui/prompts.ts +1 -1
- package/src/ui/server/middleware/errorHandler.ts +174 -0
- package/src/ui/server/routes/apps.ts +132 -0
- package/src/ui/server/routes/dashboard.ts +93 -0
- package/src/ui/server/routes/settings.ts +63 -0
- package/src/ui/server/services/appService.ts +184 -0
- package/src/ui/server/services/removalService.ts +138 -0
- package/src/utils/upgrade.ts +143 -0
- package/tsconfig.json +3 -2
- package/INDEX.md +0 -165
- /package/{ACTION_CHECKLIST.md โ MD_Files/ACTION_CHECKLIST.md} +0 -0
- /package/{APPCLEAN_SUMMARY.md โ MD_Files/APPCLEAN_SUMMARY.md} +0 -0
- /package/{CHANGELOG.md โ MD_Files/CHANGELOG.md} +0 -0
- /package/{CODE_OF_CONDUCT.md โ MD_Files/CODE_OF_CONDUCT.md} +0 -0
- /package/{CODE_REVIEW_REPORT.md โ MD_Files/CODE_REVIEW_REPORT.md} +0 -0
- /package/{COMMUNITY_POSTS.md โ MD_Files/COMMUNITY_POSTS.md} +0 -0
- /package/{DEPLOYMENT_GUIDE.md โ MD_Files/DEPLOYMENT_GUIDE.md} +0 -0
- /package/{DEPLOYMENT_STATUS.md โ MD_Files/DEPLOYMENT_STATUS.md} +0 -0
- /package/{EXECUTIVE_REPORT.md โ MD_Files/EXECUTIVE_REPORT.md} +0 -0
- /package/{GITHUB_OPTIMIZATION.md โ MD_Files/GITHUB_OPTIMIZATION.md} +0 -0
- /package/{MARKETING_SUMMARY.md โ MD_Files/MARKETING_SUMMARY.md} +0 -0
- /package/{NPM_PACKAGE_OPTIMIZATION.md โ MD_Files/NPM_PACKAGE_OPTIMIZATION.md} +0 -0
- /package/{NPM_PUBLISH.md โ MD_Files/NPM_PUBLISH.md} +0 -0
- /package/{PROJECT_SUMMARY.txt โ MD_Files/PROJECT_SUMMARY.txt} +0 -0
- /package/{QUICKSTART.md โ MD_Files/QUICKSTART.md} +0 -0
- /package/{SETUP_GITHUB.md โ MD_Files/SETUP_GITHUB.md} +0 -0
- /package/{TESTING_SUMMARY.md โ MD_Files/TESTING_SUMMARY.md} +0 -0
- /package/{setup-github.sh โ MD_Files/setup-github.sh} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { getHomeDir } from '../utils/platform';
|
|
4
|
-
import { pathExists, listDirectory, readFile } from '../utils/filesystem';
|
|
3
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
4
|
+
import { pathExists, listDirectory, readFile } from '../utils/filesystem.js';
|
|
5
5
|
import { InstalledApp, ArtifactPath } from '../types';
|
|
6
|
-
import { Logger } from '../utils/logger';
|
|
6
|
+
import { Logger } from '../utils/logger.js';
|
|
7
7
|
|
|
8
8
|
export class NpmManager {
|
|
9
9
|
private globalNpmPath: string;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Client - Wrapper for HTTP requests to AppClean server
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface ApiResponse<T> {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data?: T;
|
|
8
|
+
error?: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class ApiClient {
|
|
13
|
+
private baseUrl = '';
|
|
14
|
+
private timeout = 30000; // 30 seconds
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Make a GET request
|
|
18
|
+
*/
|
|
19
|
+
async get<T = any>(endpoint: string, options?: RequestInit): Promise<T> {
|
|
20
|
+
return this.request<T>(endpoint, { ...options, method: 'GET' });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Make a POST request
|
|
25
|
+
*/
|
|
26
|
+
async post<T = any>(
|
|
27
|
+
endpoint: string,
|
|
28
|
+
body?: any,
|
|
29
|
+
options?: RequestInit
|
|
30
|
+
): Promise<T> {
|
|
31
|
+
return this.request<T>(endpoint, {
|
|
32
|
+
...options,
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
...options?.headers,
|
|
37
|
+
},
|
|
38
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Make a PUT request
|
|
44
|
+
*/
|
|
45
|
+
async put<T = any>(
|
|
46
|
+
endpoint: string,
|
|
47
|
+
body?: any,
|
|
48
|
+
options?: RequestInit
|
|
49
|
+
): Promise<T> {
|
|
50
|
+
return this.request<T>(endpoint, {
|
|
51
|
+
...options,
|
|
52
|
+
method: 'PUT',
|
|
53
|
+
headers: {
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
...options?.headers,
|
|
56
|
+
},
|
|
57
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Make a DELETE request
|
|
63
|
+
*/
|
|
64
|
+
async delete<T = any>(endpoint: string, options?: RequestInit): Promise<T> {
|
|
65
|
+
return this.request<T>(endpoint, { ...options, method: 'DELETE' });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Generic request method
|
|
70
|
+
*/
|
|
71
|
+
private async request<T = any>(
|
|
72
|
+
endpoint: string,
|
|
73
|
+
options: RequestInit = {}
|
|
74
|
+
): Promise<T> {
|
|
75
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
76
|
+
const controller = new AbortController();
|
|
77
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(url, {
|
|
81
|
+
...options,
|
|
82
|
+
signal: controller.signal,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
clearTimeout(timeoutId);
|
|
86
|
+
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
const errorData = await this.parseErrorResponse(response);
|
|
89
|
+
throw new ApiError(
|
|
90
|
+
errorData.message || `HTTP ${response.status}`,
|
|
91
|
+
response.status,
|
|
92
|
+
errorData
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return await this.parseResponse<T>(response);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
clearTimeout(timeoutId);
|
|
99
|
+
|
|
100
|
+
if (error instanceof ApiError) {
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (error instanceof Error) {
|
|
105
|
+
if (error.name === 'AbortError') {
|
|
106
|
+
throw new ApiError('Request timeout', 408);
|
|
107
|
+
}
|
|
108
|
+
throw new ApiError(error.message, 0);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
throw new ApiError('Unknown error occurred', 0);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Parse successful response
|
|
117
|
+
*/
|
|
118
|
+
private async parseResponse<T>(response: Response): Promise<T> {
|
|
119
|
+
const contentType = response.headers.get('content-type');
|
|
120
|
+
|
|
121
|
+
if (contentType?.includes('application/json')) {
|
|
122
|
+
return response.json();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (contentType?.includes('text/')) {
|
|
126
|
+
return (await response.text()) as any;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return undefined as any;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Parse error response
|
|
134
|
+
*/
|
|
135
|
+
private async parseErrorResponse(response: Response): Promise<any> {
|
|
136
|
+
try {
|
|
137
|
+
const contentType = response.headers.get('content-type');
|
|
138
|
+
if (contentType?.includes('application/json')) {
|
|
139
|
+
return await response.json();
|
|
140
|
+
}
|
|
141
|
+
return { message: response.statusText };
|
|
142
|
+
} catch {
|
|
143
|
+
return { message: 'Unknown error' };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Custom API Error class
|
|
150
|
+
*/
|
|
151
|
+
export class ApiError extends Error {
|
|
152
|
+
constructor(
|
|
153
|
+
message: string,
|
|
154
|
+
public status: number,
|
|
155
|
+
public data?: any
|
|
156
|
+
) {
|
|
157
|
+
super(message);
|
|
158
|
+
this.name = 'ApiError';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Export singleton instance
|
|
163
|
+
export const apiClient = new ApiClient();
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppClean GUI - Main SPA Controller
|
|
3
|
+
* Initializes router, stores, and pages
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { router } from './utils/router.js';
|
|
7
|
+
import { appStore } from './state/appStore.js';
|
|
8
|
+
import { dashboardStore } from './state/dashboardStore.js';
|
|
9
|
+
import { uiStore } from './state/uiStore.js';
|
|
10
|
+
|
|
11
|
+
// Import page modules
|
|
12
|
+
import { renderDashboard } from './pages/dashboard.js';
|
|
13
|
+
import { renderAppSearch } from './pages/appSearch.js';
|
|
14
|
+
import { renderAppDetails } from './pages/appDetails.js';
|
|
15
|
+
import { renderSettings } from './pages/settings.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the SPA
|
|
19
|
+
*/
|
|
20
|
+
export function initApp(): void {
|
|
21
|
+
console.log('๐งน AppClean GUI v1.0.0 initializing...');
|
|
22
|
+
|
|
23
|
+
// Register routes
|
|
24
|
+
registerRoutes();
|
|
25
|
+
|
|
26
|
+
// Initialize stores
|
|
27
|
+
initializeStores();
|
|
28
|
+
|
|
29
|
+
// Setup UI listeners
|
|
30
|
+
setupUIListeners();
|
|
31
|
+
|
|
32
|
+
// Navigate to initial route
|
|
33
|
+
router.navigate('');
|
|
34
|
+
|
|
35
|
+
console.log('โ AppClean GUI ready');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Register all routes
|
|
40
|
+
*/
|
|
41
|
+
function registerRoutes(): void {
|
|
42
|
+
router.register('', () => {
|
|
43
|
+
uiStore.navigateTo('dashboard');
|
|
44
|
+
renderDashboard();
|
|
45
|
+
}, 'AppClean - Dashboard');
|
|
46
|
+
|
|
47
|
+
router.register('apps', () => {
|
|
48
|
+
uiStore.navigateTo('apps');
|
|
49
|
+
renderAppSearch();
|
|
50
|
+
}, 'AppClean - Apps');
|
|
51
|
+
|
|
52
|
+
router.register('apps/:appName', (params) => {
|
|
53
|
+
uiStore.navigateTo('app-details');
|
|
54
|
+
renderAppDetails(params.appName);
|
|
55
|
+
}, 'AppClean - App Details');
|
|
56
|
+
|
|
57
|
+
router.register('settings', () => {
|
|
58
|
+
uiStore.navigateTo('settings');
|
|
59
|
+
renderSettings();
|
|
60
|
+
}, 'AppClean - Settings');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Initialize stores with data
|
|
65
|
+
*/
|
|
66
|
+
async function initializeStores(): Promise<void> {
|
|
67
|
+
try {
|
|
68
|
+
// Load dashboard stats
|
|
69
|
+
await dashboardStore.loadStats();
|
|
70
|
+
|
|
71
|
+
// Load initial app list
|
|
72
|
+
await appStore.loadApps();
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('Failed to initialize stores:', error);
|
|
75
|
+
uiStore.showError('Failed to load application data');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Setup UI event listeners
|
|
81
|
+
*/
|
|
82
|
+
function setupUIListeners(): void {
|
|
83
|
+
// Subscribe to UI store changes
|
|
84
|
+
uiStore.subscribe((state) => {
|
|
85
|
+
console.log('UI State changed:', state.currentView);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Subscribe to app store changes
|
|
89
|
+
appStore.subscribe((state) => {
|
|
90
|
+
console.log(`Apps loaded: ${state.apps.length}`);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Subscribe to dashboard store changes
|
|
94
|
+
dashboardStore.subscribe((state) => {
|
|
95
|
+
if (state.stats) {
|
|
96
|
+
console.log(`Dashboard stats: ${state.stats.totalApps} apps, ${state.stats.totalSpaceUsed} bytes`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Handle route changes
|
|
101
|
+
router.onchange((route) => {
|
|
102
|
+
console.log('Navigated to:', route.path);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Theme toggle listener
|
|
106
|
+
document.addEventListener('theme-toggle', () => {
|
|
107
|
+
uiStore.toggleTheme();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Export for consumption in HTML
|
|
113
|
+
*/
|
|
114
|
+
export { appStore, dashboardStore, uiStore, router };
|
|
115
|
+
|
|
116
|
+
// Initialize on DOM ready
|
|
117
|
+
if (document.readyState === 'loading') {
|
|
118
|
+
document.addEventListener('DOMContentLoaded', initApp);
|
|
119
|
+
} else {
|
|
120
|
+
initApp();
|
|
121
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<meta name="description" content="AppClean - Intelligently remove applications and all their hidden files">
|
|
7
|
+
<meta name="theme-color" content="#3b82f6">
|
|
8
|
+
<title>AppClean - Application Remover</title>
|
|
9
|
+
|
|
10
|
+
<!-- Styles -->
|
|
11
|
+
<link rel="stylesheet" href="/static/styles/variables.css">
|
|
12
|
+
<link rel="stylesheet" href="/static/styles/base.css">
|
|
13
|
+
<link rel="stylesheet" href="/static/styles/layout.css">
|
|
14
|
+
<link rel="stylesheet" href="/static/styles/components.css">
|
|
15
|
+
<link rel="stylesheet" href="/static/styles/animations.css">
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<!-- Root container for SPA -->
|
|
19
|
+
<div id="app" class="app-root">
|
|
20
|
+
<!-- Navbar -->
|
|
21
|
+
<nav class="navbar" id="navbar">
|
|
22
|
+
<div class="container-xl">
|
|
23
|
+
<div class="flex-between">
|
|
24
|
+
<div class="flex items-center gap-4">
|
|
25
|
+
<h1 class="navbar-brand" id="navbar-brand">๐งน AppClean</h1>
|
|
26
|
+
<button class="btn btn-ghost navbar-menu-toggle" id="navbar-menu-toggle" aria-label="Toggle navigation">
|
|
27
|
+
<span class="hamburger">โฐ</span>
|
|
28
|
+
</button>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="flex items-center gap-2">
|
|
31
|
+
<button class="btn btn-ghost btn-sm" id="theme-toggle" aria-label="Toggle dark mode">
|
|
32
|
+
<span class="theme-icon">๐</span>
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</nav>
|
|
38
|
+
|
|
39
|
+
<!-- Main layout -->
|
|
40
|
+
<div class="app-layout flex">
|
|
41
|
+
<!-- Sidebar -->
|
|
42
|
+
<aside class="sidebar" id="sidebar">
|
|
43
|
+
<div class="sidebar-nav">
|
|
44
|
+
<nav class="nav-links">
|
|
45
|
+
<a href="#/" class="nav-link active" data-view="dashboard">
|
|
46
|
+
<span class="nav-icon">๐</span>
|
|
47
|
+
<span class="nav-label">Dashboard</span>
|
|
48
|
+
</a>
|
|
49
|
+
<a href="#/apps" class="nav-link" data-view="apps">
|
|
50
|
+
<span class="nav-icon">๐ฆ</span>
|
|
51
|
+
<span class="nav-label">Apps</span>
|
|
52
|
+
</a>
|
|
53
|
+
<a href="#/settings" class="nav-link" data-view="settings">
|
|
54
|
+
<span class="nav-icon">โ๏ธ</span>
|
|
55
|
+
<span class="nav-label">Settings</span>
|
|
56
|
+
</a>
|
|
57
|
+
</nav>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="sidebar-footer">
|
|
60
|
+
<a href="https://github.com/praveenkay/AppClean" target="_blank" rel="noopener" class="sidebar-link">
|
|
61
|
+
<span class="nav-icon">๐ฌ</span>
|
|
62
|
+
<span class="nav-label">GitHub</span>
|
|
63
|
+
</a>
|
|
64
|
+
</div>
|
|
65
|
+
</aside>
|
|
66
|
+
|
|
67
|
+
<!-- Main content -->
|
|
68
|
+
<main class="main-content" id="main-content">
|
|
69
|
+
<div class="container-xl">
|
|
70
|
+
<!-- Pages will be rendered here -->
|
|
71
|
+
<div id="page-container" class="page-container">
|
|
72
|
+
<!-- Loading skeleton -->
|
|
73
|
+
<div class="loading-state" id="loading-state">
|
|
74
|
+
<div class="spinner-lg spinner"></div>
|
|
75
|
+
<p class="text-center text-muted mt-4">Loading AppClean...</p>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</main>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<!-- Modals -->
|
|
83
|
+
<div class="modal-backdrop" id="modal-backdrop">
|
|
84
|
+
<div class="modal" id="modal" role="dialog" aria-labelledby="modal-title">
|
|
85
|
+
<div class="modal-header">
|
|
86
|
+
<h2 class="modal-title" id="modal-title">Dialog</h2>
|
|
87
|
+
<button class="modal-close" id="modal-close" aria-label="Close dialog">×</button>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="modal-body" id="modal-body">
|
|
90
|
+
<!-- Content will be rendered here -->
|
|
91
|
+
</div>
|
|
92
|
+
<div class="modal-footer" id="modal-footer">
|
|
93
|
+
<!-- Buttons will be rendered here -->
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<!-- Notifications -->
|
|
99
|
+
<div class="notifications-container" id="notifications-container" role="region" aria-label="Notifications" aria-live="polite">
|
|
100
|
+
<!-- Notifications will be rendered here -->
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<!-- Scripts -->
|
|
105
|
+
<script type="module" src="/static/app.js"></script>
|
|
106
|
+
</body>
|
|
107
|
+
</html>
|