Major updates: LinkedIn auto-posting, timezone fixes, and Docker improvements
Features: - Add LinkedIn OAuth integration and auto-posting functionality - Add scheduler service for automated post publishing - Add metadata field to generated_posts for LinkedIn URLs - Add privacy policy page for LinkedIn API compliance - Add company management features and employee accounts - Add license key system for company registrations Fixes: - Fix timezone issues (use UTC consistently across app) - Fix datetime serialization errors in database operations - Fix scheduling timezone conversion (local time to UTC) - Fix import errors (get_database -> db) Infrastructure: - Update Docker setup to use port 8001 (avoid conflicts) - Add SSL support with nginx-proxy and Let's Encrypt - Add LinkedIn setup documentation - Add migration scripts for schema updates Services: - Add linkedin_service.py for LinkedIn API integration - Add scheduler_service.py for background job processing - Add storage_service.py for Supabase Storage - Add email_service.py improvements - Add encryption utilities for token storage Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
126
src/web/templates/user/register_ghostwriter.html
Normal file
126
src/web/templates/user/register_ghostwriter.html
Normal file
@@ -0,0 +1,126 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ghostwriter Registrierung - LinkedIn Posts</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
'brand': {
|
||||
'bg': '#3d4848',
|
||||
'bg-light': '#4a5858',
|
||||
'bg-dark': '#2d3838',
|
||||
'highlight': '#ffc700',
|
||||
'highlight-dark': '#e6b300',
|
||||
},
|
||||
'linkedin': '#0A66C2'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
body { background-color: #3d4848; }
|
||||
.btn-linkedin { background-color: #0A66C2; }
|
||||
.btn-linkedin:hover { background-color: #004182; }
|
||||
.card-bg { background-color: #4a5858; border-color: #5a6868; }
|
||||
.input-bg { background-color: #3d4848; border-color: #5a6868; }
|
||||
.input-bg:focus { border-color: #ffc700; outline: none; }
|
||||
.btn-primary { background-color: #ffc700; color: #2d3838; }
|
||||
.btn-primary:hover { background-color: #e6b300; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="text-gray-100 min-h-screen flex items-center justify-center">
|
||||
<div class="w-full max-w-md px-4">
|
||||
<div class="card-bg rounded-xl border p-8">
|
||||
<div class="text-center mb-8">
|
||||
<img src="/static/logo.png" alt="Logo" class="h-16 w-auto mx-auto mb-4">
|
||||
<h1 class="text-2xl font-bold text-white mb-2">Ghostwriter Konto</h1>
|
||||
<p class="text-gray-400">Erstelle dein persönliches Konto</p>
|
||||
</div>
|
||||
|
||||
{% if error %}
|
||||
<div class="bg-red-900/50 border border-red-500 text-red-200 px-4 py-3 rounded-lg mb-6">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- LinkedIn OAuth -->
|
||||
<div class="mb-6">
|
||||
<a href="/auth/linkedin?account_type=ghostwriter" class="w-full btn-linkedin text-white font-medium py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-3">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
|
||||
</svg>
|
||||
Mit LinkedIn registrieren (empfohlen)
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="relative my-6">
|
||||
<div class="absolute inset-0 flex items-center">
|
||||
<div class="w-full border-t border-gray-600"></div>
|
||||
</div>
|
||||
<div class="relative flex justify-center text-sm">
|
||||
<span class="px-4 bg-brand-bg-light text-gray-400">oder mit E-Mail</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email/Password Form -->
|
||||
<form method="POST" action="/register/ghostwriter" class="space-y-4">
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-300 mb-1">E-Mail</label>
|
||||
<input type="email" id="email" name="email" required
|
||||
class="w-full input-bg border rounded-lg px-4 py-2 text-white"
|
||||
placeholder="deine@email.de">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-medium text-gray-300 mb-1">Passwort</label>
|
||||
<input type="password" id="password" name="password" required minlength="8"
|
||||
class="w-full input-bg border rounded-lg px-4 py-2 text-white"
|
||||
placeholder="Mindestens 8 Zeichen">
|
||||
<p class="text-xs text-gray-500 mt-1">Mind. 8 Zeichen, 1 Großbuchstabe, 1 Zahl</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password_confirm" class="block text-sm font-medium text-gray-300 mb-1">Passwort bestätigen</label>
|
||||
<input type="password" id="password_confirm" name="password_confirm" required
|
||||
class="w-full input-bg border rounded-lg px-4 py-2 text-white"
|
||||
placeholder="Passwort wiederholen">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full btn-primary font-medium py-3 px-4 rounded-lg transition-colors">
|
||||
Konto erstellen
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="text-center pt-6 mt-6 border-t border-gray-600">
|
||||
<p class="text-gray-400 text-sm">
|
||||
Du hast bereits ein Konto?
|
||||
<a href="/login" class="text-brand-highlight hover:underline">Anmelden</a>
|
||||
</p>
|
||||
<p class="text-gray-500 text-sm mt-2">
|
||||
<a href="/register" class="hover:text-gray-300">← Kontotyp ändern</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Password confirmation validation
|
||||
const form = document.querySelector('form');
|
||||
const password = document.getElementById('password');
|
||||
const passwordConfirm = document.getElementById('password_confirm');
|
||||
|
||||
form.addEventListener('submit', function(e) {
|
||||
if (password.value !== passwordConfirm.value) {
|
||||
e.preventDefault();
|
||||
alert('Passwörter stimmen nicht überein');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user