refactor: unify docker deployment and restructure frontend architecture

This commit implements a unified Docker deployment strategy, moving from separate frontend and backend images to a single, multi-stage build image containing both services. It also introduces a major reorganization of the frontend directory structure and simplifies the environment configuration.

Key changes:
- **Deployment**: Added a multi-stage `Dockerfile` and `docker-entrypoint.sh` to package the Go backend and Nginx-served frontend into a single container.
- **CI/CD**: Updated GitHub Actions workflows (`ci-cd.yml`, `release.yml`) to build and push the new unified image instead of separate ones.
- **Frontend Refactor**: Reorganized `frontend/src/pages` into a domain-driven directory structure (e.g., `auth/`, `admin/`, `content/`, `communication/`, `productivity/`, `settings/`, `misc/`).
- **Configuration**: Simplified `.env.example` and updated `docker-compose.yml` to reflect the unified service model and single host port.
- **Cleanup**: Removed deprecated `docker-compose.demo.yml`, `docker-compose.prod.yml`, and various unused frontend components and services.
- **Backend**: Refactored configuration loading to use exported `GetDurationEnv` for better consistency.
This commit is contained in:
Tomas Dvorak
2026-05-10 10:48:41 +02:00
parent c6a99c7e21
commit 6c448b336a
71 changed files with 135367 additions and 4481 deletions
+89
View File
@@ -0,0 +1,89 @@
import { createSignal, onMount } from 'solid-js';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { getApiV1BaseUrl } from '@/lib/api-url';
import { useAuth } from '@/lib/auth';
export const AuthCallback = () => {
const [status, setStatus] = createSignal<'loading' | 'success' | 'error'>('loading');
const [message, setMessage] = createSignal('Processing authentication...');
const { setAuth } = useAuth();
onMount(async () => {
try {
const apiBase = getApiV1BaseUrl();
const params = new URLSearchParams(window.location.search);
const token = params.get('token');
if (!token) {
throw new Error('Missing token');
}
window.history.replaceState({}, '', '/auth/callback');
const res = await fetch(`${apiBase}/auth/me`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!res.ok) {
throw new Error('Authentication failed');
}
const data = await res.json();
if (!data?.user) {
throw new Error('Invalid authentication response');
}
setAuth(token, data.user);
setStatus('success');
setMessage('Authentication successful! Redirecting...');
window.location.replace('/app');
} catch (error) {
setStatus('error');
setMessage(error instanceof Error ? error.message : 'Authentication failed');
}
});
return (
<div class="min-h-screen flex items-center justify-center bg-background">
<Card class="p-8 max-w-md w-full">
<div class="text-center">
{status() === 'loading' && (
<div class="flex flex-col items-center gap-4">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
<p class="text-lg text-foreground">{message()}</p>
</div>
)}
{status() === 'success' && (
<div class="flex flex-col items-center gap-4">
<div class="w-12 h-12 bg-primary rounded-full flex items-center justify-center">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
</div>
<p class="text-lg text-primary font-medium">{message()}</p>
</div>
)}
{status() === 'error' && (
<div class="flex flex-col items-center gap-4">
<div class="w-12 h-12 bg-destructive rounded-full flex items-center justify-center">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
<p class="text-lg text-destructive font-medium">{message()}</p>
<Button onClick={() => window.location.href = '/login'}>
Back to Login
</Button>
</div>
)}
</div>
</Card>
</div>
);
};