diff --git a/Dockerfile b/Dockerfile index 0e45c3b..ef94008 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,6 +44,9 @@ RUN cd client && npm install # Copy application code COPY . . +# Build frontend +RUN cd client && npm run build + # Copy nginx configuration COPY nginx.conf /etc/nginx/nginx.conf @@ -55,7 +58,7 @@ nodaemon=true user=root [program:dockerd] -command=dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 --storage-driver=overlay2 --iptables=true --ip-forward=true --ip-masq=true +command=dockerd --host=unix:///var/run/docker.sock --storage-driver=overlay2 --exec-opt native.cgroupdriver=cgroupfs --iptables=true --ip-forward=true --ip-masq=true autostart=true autorestart=true stderr_logfile=/var/log/supervisor/dockerd.err.log @@ -71,14 +74,14 @@ stderr_logfile=/var/log/supervisor/docker-pull.err.log stdout_logfile=/var/log/supervisor/docker-pull.out.log priority=150 -[program:dev-server] -command=npm run dev +[program:backend] +command=npm run serve:server directory=/app autostart=true autorestart=true -stderr_logfile=/var/log/supervisor/dev-server.err.log -stdout_logfile=/var/log/supervisor/dev-server.out.log -environment=NODE_ENV=development +stderr_logfile=/var/log/supervisor/backend.err.log +stdout_logfile=/var/log/supervisor/backend.out.log +environment=NODE_ENV=production priority=200 [program:nginx] @@ -95,10 +98,10 @@ COPY start.sh /app/start.sh RUN sed -i 's/\r$//' /app/start.sh && chmod +x /app/start.sh # Expose ports -EXPOSE 80 3000 5173 +EXPOSE 80 3000 # Set environment variables -ENV NODE_ENV=development +ENV NODE_ENV=production ENV DOCKER_HOST=unix:///var/run/docker.sock ENV DOCKER_TLS_CERTDIR="" diff --git a/client/src/App.svelte b/client/src/App.svelte index b2961b3..614b057 100644 --- a/client/src/App.svelte +++ b/client/src/App.svelte @@ -2,11 +2,13 @@ import { onMount } from 'svelte'; import Auth from './lib/Auth.svelte'; import Dashboard from './lib/Dashboard.svelte'; + import AdminPanel from './lib/AdminPanel.svelte'; import { API_BASE } from './config.js'; let isAuthenticated = false; let user = null; let spaces = []; + let showAdminPanel = false; onMount(() => { const storedAuth = localStorage.getItem('auth_token'); @@ -25,12 +27,13 @@ }); function handleAuthenticated(event) { - const { authorization, username, email } = event.detail; + const { authorization, username, email, is_admin } = event.detail; user = { authorization, username, - email + email, + is_admin }; localStorage.setItem('auth_token', authorization); @@ -86,12 +89,24 @@
{#if isAuthenticated && user} - + {#if showAdminPanel && user.is_admin} +
+ +
+ + {:else} + {#if user.is_admin} + + {/if} + + {/if} {:else} {/if} @@ -102,4 +117,23 @@ width: 100%; min-height: 100vh; } + + .admin-header, .admin-link { + padding: 10px 20px; + background-color: #f8f9fa; + border-bottom: 1px solid #ddd; + } + + .admin-header button, .admin-link button { + padding: 8px 16px; + background-color: #007bff; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + } + + .admin-header button:hover, .admin-link button:hover { + background-color: #0056b3; + } \ No newline at end of file diff --git a/client/src/config.js b/client/src/config.js index 6157f31..bfce848 100644 --- a/client/src/config.js +++ b/client/src/config.js @@ -1,4 +1,4 @@ -export const API_BASE = 'https://t0080w08wcockgs44ws8w880.b.selfhosted.hackclub.com/api/v1'; +export const API_BASE = 'http://localhost:2593/api/v1'; export const ERROR_MESSAGES = { NETWORK_ERROR: 'Network error. Please try again.', diff --git a/client/src/lib/AdminPanel.svelte b/client/src/lib/AdminPanel.svelte new file mode 100644 index 0000000..386b68c --- /dev/null +++ b/client/src/lib/AdminPanel.svelte @@ -0,0 +1,348 @@ + + +
+

Admin Panel

+ + {#if loading} +

Loading...

+ {:else} +
+ + + +
+ + {#if activeTab === 'analytics'} +
+
+

Total Users

+

{analytics.totalUsers}

+
+
+

Total Spaces

+

{analytics.totalSpaces}

+
+
+

Active Spaces

+

{analytics.activeSpaces}

+
+
+ {/if} + + {#if activeTab === 'users'} +
+ + + + + + + + + + + + + + {#each users as user} + + + + + + + + + + {/each} + +
IDEmailUsernameSpacesMax SpacesAdminActions
{user.id}{user.email}{user.username}{user.spaceCount} + handleMaxSpacesChange(user.id, e.target.value)} + min="0" + /> + + toggleAdmin(user.id, user.is_admin)} + /> + + +
+
+ {/if} + + {#if activeTab === 'spaces'} +
+ + + + + + + + + + + + + + {#each spaces as space} + + + + + + + + + + {/each} + +
IDTypeOwnerEmailStatusPortActions
{space.id}{space.type}{space.username}{space.email}{space.running ? 'Running' : 'Stopped'}{space.port} + +
+
+ {/if} + {/if} +
+ + diff --git a/client/src/lib/Auth.svelte b/client/src/lib/Auth.svelte index 39950da..00e1217 100644 --- a/client/src/lib/Auth.svelte +++ b/client/src/lib/Auth.svelte @@ -1,6 +1,7 @@ - - - + Hack Club diff --git a/client/src/lib/Dashboard.svelte b/client/src/lib/Dashboard.svelte index f501a9c..2f2114c 100644 --- a/client/src/lib/Dashboard.svelte +++ b/client/src/lib/Dashboard.svelte @@ -1,6 +1,7 @@ - - - -
@@ -302,46 +299,52 @@
-
- -
- {#if showPassword} - - {:else} - - {/if} - + +
- + {:else} +
+
+ {/if} {#if error}
{error}
@@ -350,7 +353,7 @@ @@ -377,13 +380,6 @@

Space ID: {space.id}

- {#if space.url} -

URL: - - {space.url} - -

- {/if}

Created: {new Date(space.created_at).toLocaleString()}

@@ -397,16 +393,10 @@ {actionLoading[space.id]}... {:else} - {#if space.status?.toLowerCase() === 'running'} - - {#if space.url} + {#if space.running || space.status?.toLowerCase() === 'running'} + {#if space.access_url} {/if} + {:else}