hello
This commit is contained in:
18
app/templates/auth/auth_base.html
Normal file
18
app/templates/auth/auth_base.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" data-theme="cupcake">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}Email Organizer - Authentication{% endblock %}</title>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||||
|
{% block head %}{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body class="min-h-screen bg-base-200 flex items-center justify-center p-4">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,72 +1,62 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "auth/auth_base.html" %}
|
||||||
<html lang="en" data-theme="cupcake">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Login - Email Organizer</title>
|
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
||||||
</head>
|
|
||||||
<body class="min-h-screen bg-base-200 flex items-center justify-center p-4">
|
|
||||||
<div class="card bg-base-100 shadow-xl w-full max-w-sm">
|
|
||||||
<div class="card-body p-6">
|
|
||||||
<div class="text-center mb-6">
|
|
||||||
<h1 class="text-2xl font-bold text-primary">
|
|
||||||
<i class="fas fa-envelope mr-2"></i>
|
|
||||||
Email Organizer
|
|
||||||
</h1>
|
|
||||||
<p class="text-base-content/70 text-sm mt-1">Sign in to your account</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
{% block title %}Login - Email Organizer{% endblock %}
|
||||||
{% if messages %}
|
|
||||||
{% for category, message in messages %}
|
|
||||||
<div class="alert alert-{{ 'error' if category == 'error' else 'success' }} mb-4">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<span>{{ message }}</span>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
<form method="POST" action="{{ url_for('auth.login') }}" class="space-y-4">
|
{% block content %}
|
||||||
<label for="email" class="floating-label">
|
<div class="card bg-base-100 shadow-xl w-full max-w-sm">
|
||||||
<span class="label-text text-sm font-medium">Email</span>
|
<div class="card-body p-6">
|
||||||
<input type="email" id="email" name="email" class="input input-bordered w-full" placeholder="Enter your email" required>
|
<div class="text-center mb-6">
|
||||||
</label>
|
<h1 class="text-2xl font-bold text-primary">
|
||||||
|
<i class="fas fa-envelope mr-2"></i>
|
||||||
|
Email Organizer
|
||||||
|
</h1>
|
||||||
|
<p class="text-base-content/70 text-sm mt-1">Sign in to your account</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<label for="password" class="floating-label">
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
<span class="label-text text-sm font-medium">Password</span>
|
{% if messages %}
|
||||||
<input type="password" id="password" name="password" class="input input-bordered w-full"
|
{% for category, message in messages %}
|
||||||
placeholder="Enter your password" required>
|
<div class="alert alert-{{ 'error' if category == 'error' else 'success' }} mb-4">
|
||||||
</label>
|
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
<span>{{ message }}</span>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
<label class="label cursor-pointer justify-start">
|
<form method="POST" action="{{ url_for('auth.login') }}" class="space-y-4">
|
||||||
<input type="checkbox" name="remember" class="checkbox checkbox-primary">
|
<label for="email" class="floating-label">
|
||||||
<span class="label-text text-sm">Remember me</span>
|
<span class="label-text text-sm font-medium">Email</span>
|
||||||
</label>
|
<input type="email" id="email" name="email" class="input input-bordered w-full" placeholder="Enter your email" required>
|
||||||
|
</label>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary w-full">
|
<label for="password" class="floating-label">
|
||||||
<i class="fas fa-sign-in-alt mr-2"></i>
|
<span class="label-text text-sm font-medium">Password</span>
|
||||||
Sign In
|
<input type="password" id="password" name="password" class="input input-bordered w-full"
|
||||||
</button>
|
placeholder="Enter your password" required>
|
||||||
</form>
|
</label>
|
||||||
|
|
||||||
<div class="text-center mt-6">
|
<label class="label cursor-pointer justify-start">
|
||||||
<p class="text-base-content/70 text-sm">
|
<input type="checkbox" name="remember" class="checkbox checkbox-primary">
|
||||||
Don't have an account?
|
<span class="label-text text-sm">Remember me</span>
|
||||||
<a href="{{ url_for('auth.signup') }}" class="link link-primary">
|
</label>
|
||||||
Sign up
|
|
||||||
</a>
|
<button type="submit" class="btn btn-primary w-full">
|
||||||
</p>
|
<i class="fas fa-sign-in-alt mr-2"></i>
|
||||||
</div>
|
Sign In
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="text-center mt-6">
|
||||||
|
<p class="text-base-content/70 text-sm">
|
||||||
|
Don't have an account?
|
||||||
|
<a href="{{ url_for('auth.signup') }}" class="link link-primary">
|
||||||
|
Sign up
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</div>
|
||||||
</html>
|
{% endblock %}
|
||||||
@@ -1,125 +1,115 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "auth/auth_base.html" %}
|
||||||
<html lang="en" data-theme="cupcake">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Create Account - Email Organizer</title>
|
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
||||||
</head>
|
|
||||||
<body class="min-h-screen bg-base-200 flex items-center justify-center p-4">
|
|
||||||
<div class="card bg-base-100 shadow-xl w-full max-w-md">
|
|
||||||
<div class="card-body p-6 max-w-sm">
|
|
||||||
<div class="text-center mb-6">
|
|
||||||
<h1 class="text-2xl font-bold text-primary">
|
|
||||||
<i class="fas fa-envelope mr-2"></i>
|
|
||||||
Email Organizer
|
|
||||||
</h1>
|
|
||||||
<p class="text-base-content/70 text-sm mt-1">Create your account</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
{% block title %}Create Account - Email Organizer{% endblock %}
|
||||||
{% if messages %}
|
|
||||||
{% for category, message in messages %}
|
|
||||||
<div class="alert alert-{{ 'error' if category == 'error' else 'success' }} mb-4">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<span>{{ message }}</span>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
{% if errors %}
|
{% block content %}
|
||||||
<div class="alert alert-error mb-4">
|
<div class="card bg-base-100 shadow-xl w-full max-w-md">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
<div class="card-body p-6 max-w-sm">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<div class="text-center mb-6">
|
||||||
</svg>
|
<h1 class="text-2xl font-bold text-primary">
|
||||||
<span>Please fix the following errors:</span>
|
<i class="fas fa-envelope mr-2"></i>
|
||||||
</div>
|
Email Organizer
|
||||||
<ul class="text-error text-sm mb-4">
|
</h1>
|
||||||
{% for error in errors %}
|
<p class="text-base-content/70 text-sm mt-1">Create your account</p>
|
||||||
<li>• {{ error }}</li>
|
</div>
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
|
{% if messages %}
|
||||||
|
{% for category, message in messages %}
|
||||||
|
<div class="alert alert-{{ 'error' if category == 'error' else 'success' }} mb-4">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
<span>{{ message }}</span>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
<form method="POST" action="{{ url_for('auth.signup') }}" class="space-y-4">
|
{% if errors %}
|
||||||
<div class="form-control">
|
<div class="alert alert-error mb-4">
|
||||||
<label for="first_name" class="label">
|
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
||||||
<span class="label-text text-sm font-medium">First Name</span>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
</label>
|
</svg>
|
||||||
<input type="text" id="first_name" name="first_name" class="input input-bordered w-full"
|
<span>Please fix the following errors:</span>
|
||||||
placeholder="Enter your first name" value="{{ first_name or '' }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control">
|
|
||||||
<label for="last_name" class="label">
|
|
||||||
<span class="label-text text-sm font-medium">Last Name</span>
|
|
||||||
</label>
|
|
||||||
<input type="text" id="last_name" name="last_name" class="input input-bordered w-full"
|
|
||||||
placeholder="Enter your last name" value="{{ last_name or '' }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control">
|
|
||||||
<label for="email" class="label">
|
|
||||||
<span class="label-text text-sm font-medium">Email</span>
|
|
||||||
</label>
|
|
||||||
<input type="email" id="email" name="email" class="input input-bordered w-full"
|
|
||||||
placeholder="Enter your email" value="{{ email or '' }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control">
|
|
||||||
<label for="password" class="label">
|
|
||||||
<span class="label-text text-sm font-medium">Password</span>
|
|
||||||
</label>
|
|
||||||
<input type="password" id="password" name="password" class="input input-bordered w-full"
|
|
||||||
placeholder="Create a password" required>
|
|
||||||
<span class="label-text-alt text-xs text-base-content/50">
|
|
||||||
Password must be at least 8 characters with uppercase, lowercase, and numbers
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control">
|
|
||||||
<label for="confirm_password" class="label">
|
|
||||||
<span class="label-text text-sm font-medium">Confirm Password</span>
|
|
||||||
</label>
|
|
||||||
<input type="password" id="confirm_password" name="confirm_password" class="input input-bordered w-full"
|
|
||||||
placeholder="Confirm your password" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control">
|
|
||||||
<label class="label cursor-pointer justify-start">
|
|
||||||
<input type="checkbox" name="terms" class="checkbox checkbox-primary" required>
|
|
||||||
<span class="label-text text-sm">
|
|
||||||
I agree to the
|
|
||||||
<a href="#" class="link link-primary">Terms of Service</a>
|
|
||||||
and
|
|
||||||
<a href="#" class="link link-primary">Privacy Policy</a>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary w-full">
|
|
||||||
<i class="fas fa-user-plus mr-2"></i>
|
|
||||||
Create Account
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div class="text-center mt-6">
|
|
||||||
<p class="text-base-content/70 text-sm">
|
|
||||||
Already have an account?
|
|
||||||
<a href="{{ url_for('auth.login') }}" class="link link-primary">
|
|
||||||
Sign in
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
<ul class="text-error text-sm mb-4">
|
||||||
|
{% for error in errors %}
|
||||||
|
<li>• {{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form method="POST" action="{{ url_for('auth.signup') }}" class="space-y-4">
|
||||||
|
<div class="form-control">
|
||||||
|
<label for="first_name" class="label">
|
||||||
|
<span class="label-text text-sm font-medium">First Name</span>
|
||||||
|
</label>
|
||||||
|
<input type="text" id="first_name" name="first_name" class="input input-bordered w-full"
|
||||||
|
placeholder="Enter your first name" value="{{ first_name or '' }}" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-control">
|
||||||
|
<label for="last_name" class="label">
|
||||||
|
<span class="label-text text-sm font-medium">Last Name</span>
|
||||||
|
</label>
|
||||||
|
<input type="text" id="last_name" name="last_name" class="input input-bordered w-full"
|
||||||
|
placeholder="Enter your last name" value="{{ last_name or '' }}" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-control">
|
||||||
|
<label for="email" class="label">
|
||||||
|
<span class="label-text text-sm font-medium">Email</span>
|
||||||
|
</label>
|
||||||
|
<input type="email" id="email" name="email" class="input input-bordered w-full"
|
||||||
|
placeholder="Enter your email" value="{{ email or '' }}" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-control">
|
||||||
|
<label for="password" class="label">
|
||||||
|
<span class="label-text text-sm font-medium">Password</span>
|
||||||
|
</label>
|
||||||
|
<input type="password" id="password" name="password" class="input input-bordered w-full"
|
||||||
|
placeholder="Create a password" required>
|
||||||
|
<span class="label-text-alt text-xs text-base-content/50">
|
||||||
|
Password must be at least 8 characters with uppercase, lowercase, and numbers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-control">
|
||||||
|
<label for="confirm_password" class="label">
|
||||||
|
<span class="label-text text-sm font-medium">Confirm Password</span>
|
||||||
|
</label>
|
||||||
|
<input type="password" id="confirm_password" name="confirm_password" class="input input-bordered w-full"
|
||||||
|
placeholder="Confirm your password" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-control">
|
||||||
|
<label class="label cursor-pointer justify-start">
|
||||||
|
<input type="checkbox" name="terms" class="checkbox checkbox-primary" required>
|
||||||
|
<span class="label-text text-sm">
|
||||||
|
I agree to the
|
||||||
|
<a href="#" class="link link-primary">Terms of Service</a>
|
||||||
|
and
|
||||||
|
<a href="#" class="link link-primary">Privacy Policy</a>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary w-full">
|
||||||
|
<i class="fas fa-user-plus mr-2"></i>
|
||||||
|
Create Account
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="text-center mt-6">
|
||||||
|
<p class="text-base-content/70 text-sm">
|
||||||
|
Already have an account?
|
||||||
|
<a href="{{ url_for('auth.login') }}" class="link link-primary">
|
||||||
|
Sign in
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</div>
|
||||||
</html>
|
{% endblock %}
|
||||||
33
app/templates/base.html
Normal file
33
app/templates/base.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" data-theme="cupcake">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}Email Organizer - Prototype{% endblock %}</title>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||||
|
<style>
|
||||||
|
@keyframes shake {
|
||||||
|
0%, 100% { transform: translateX(0); }
|
||||||
|
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
|
||||||
|
20%, 40%, 60%, 80% { transform: translateX(5px); }
|
||||||
|
}
|
||||||
|
.shake {
|
||||||
|
animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% block head %}{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body class="min-h-screen flex flex-col" x-data="{}" x-on:open-modal.window="$refs.modal.showModal()"
|
||||||
|
x-on:close-modal.window="$refs.modal.close()">
|
||||||
|
{% block header %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
|
||||||
|
{% block modal %}{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,140 +1,41 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en" data-theme="cupcake">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Email Organizer - Prototype</title>
|
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
|
||||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
||||||
<style>
|
|
||||||
@keyframes shake {
|
|
||||||
0%, 100% { transform: translateX(0); }
|
|
||||||
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
|
|
||||||
20%, 40%, 60%, 80% { transform: translateX(5px); }
|
|
||||||
}
|
|
||||||
.shake {
|
|
||||||
animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body class="min-h-screen flex flex-col" x-data="{}" x-on:open-modal.window="$refs.modal.showModal()"
|
|
||||||
x-on:close-modal.window="$refs.modal.close()">
|
|
||||||
<header class="bg-base-100 border-b border-base-300 p-4 flex justify-between shadow-sm fixed top-0 left-0 right-0 z-20">
|
|
||||||
<div>
|
|
||||||
<h1 class="text-2xl font-bold text-primary flex items-center">
|
|
||||||
<i class="fas fa-envelope mr-2"></i>
|
|
||||||
Email Organizer
|
|
||||||
</h1>
|
|
||||||
<p class="text-sm mt-1 text-base-content/70">AI-powered email organization</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center space-x-4">
|
{% block title %}Email Organizer - Prototype{% endblock %}
|
||||||
<button class="relative p-2 rounded-full hover:bg-base-300 btn-circle">
|
|
||||||
<i class="fas fa-bell"></i>
|
|
||||||
<span class="badge badge-sm badge-secondary absolute -top-1 -right-1">3</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="relative" x-data="{ open: false }" @click.outside="open = false">
|
{% block header %}
|
||||||
<button id="user-menu-button" class="flex items-center space-x-2 p-2 rounded-lg hover:bg-base-300"
|
{% include "partials/header.html" %}
|
||||||
@click="open = !open">
|
{% endblock %}
|
||||||
<div class="w-8 h-8 rounded-full bg-primary flex items-center justify-center">
|
|
||||||
<span class="font-semibold text-primary-content">{{ current_user.first_name[0] }}{{
|
{% block content %}
|
||||||
current_user.last_name[0] }}</span>
|
<div class="flex">
|
||||||
</div>
|
{% include "partials/sidebar.html" %}
|
||||||
<span class="hidden md:inline">{{ current_user.first_name }} {{ current_user.last_name }}</span>
|
|
||||||
<i class="fas fa-chevron-down"></i>
|
<!-- Main Content -->
|
||||||
|
<div class="flex-1 ml-64 mt-16 flex flex-col">
|
||||||
|
<!-- Top Bar -->
|
||||||
|
|
||||||
|
<!-- Main Content Area -->
|
||||||
|
<main class="flex-1 p-6 overflow-auto bg-base-100">
|
||||||
|
<div class="flex justify-between items-center mb-6">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-2xl font-bold">Email Folders</h2>
|
||||||
|
<p class="text-base-content/70">Create and manage your email organization rules</p>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" hx-get="/api/folders/new" hx-target="#modal-holder"
|
||||||
|
hx-swap="innerHTML">
|
||||||
|
<i class="fas fa-plus mr-2"></i>
|
||||||
|
Add Folder
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- User Dropdown -->
|
|
||||||
<div id="user-dropdown"
|
|
||||||
class="user-dropdown absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-base-100 z-10"
|
|
||||||
x-show="open">
|
|
||||||
<a href="#" class="block px-4 py-2 text-sm hover:bg-base-300">Profile</a>
|
|
||||||
<a href="#" class="block px-4 py-2 text-sm hover:bg-base-300">Settings</a>
|
|
||||||
<a href="{{ url_for('auth.logout') }}" class="block px-4 py-2 text-sm hover:bg-base-300">Logout</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="flex">
|
|
||||||
<div class="sidebar w-64 p-4 flex flex-col bg-base-200 shadow-lg fixed top-16 left-0 bottom-0 z-10">
|
|
||||||
|
|
||||||
<nav class="flex-grow menu bg-transparent rounded-lg">
|
<section id="folders-list" class="mb-12">
|
||||||
<div class="active">
|
{% include 'partials/folders_list.html' %}
|
||||||
<a class="btn btn-ghost justify-start">
|
</section>
|
||||||
<i class="fas fa-folder mr-3 text-primary"></i>
|
</main>
|
||||||
Folders
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a class="btn btn-ghost justify-start">
|
|
||||||
<i class="fas fa-inbox mr-3 text-secondary"></i>
|
|
||||||
Inbox
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a class="btn btn-ghost justify-start">
|
|
||||||
<i class="fas fa-cog mr-3 text-accent"></i>
|
|
||||||
Settings
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a class="btn btn-ghost justify-start">
|
|
||||||
<i class="fas fa-chart-bar mr-3 text-info"></i>
|
|
||||||
Analytics
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a class="btn btn-ghost justify-start">
|
|
||||||
<i class="fas fa-question-circle mr-3 text-warning"></i>
|
|
||||||
Help
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="mt-auto pt-4 border-t border-base-300">
|
|
||||||
<div>
|
|
||||||
<a href="{{ url_for('auth.logout') }}" class="btn btn-ghost justify-start">
|
|
||||||
<i class="fas fa-sign-out-alt mr-3 text-error"></i>
|
|
||||||
Logout
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Main Content -->
|
|
||||||
<div class="flex-1 ml-64 mt-16 flex flex-col">
|
|
||||||
<!-- Top Bar -->
|
|
||||||
|
|
||||||
<!-- Main Content Area -->
|
|
||||||
<main class="flex-1 p-6 overflow-auto bg-base-100">
|
|
||||||
<div class="flex justify-between items-center mb-6">
|
|
||||||
<div>
|
|
||||||
<h2 class="text-2xl font-bold">Email Folders</h2>
|
|
||||||
<p class="text-base-content/70">Create and manage your email organization rules</p>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-primary" hx-get="/api/folders/new" hx-target="#modal-holder"
|
|
||||||
hx-swap="innerHTML">
|
|
||||||
<i class="fas fa-plus mr-2"></i>
|
|
||||||
Add Folder
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section id="folders-list" class="mb-12">
|
|
||||||
{% include 'partials/folders_list.html' %}
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Modal Holder -->
|
</div>
|
||||||
<dialog id="modal-holder" x-ref="modal" class="modal">
|
{% endblock %}
|
||||||
<!-- Modals will be loaded here via HTMX -->
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
</body>
|
{% block modal %}
|
||||||
|
{% include "partials/modal_holder.html" %}
|
||||||
</html>
|
{% endblock %}
|
||||||
37
app/templates/partials/header.html
Normal file
37
app/templates/partials/header.html
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<header class="bg-base-100 border-b border-base-300 p-4 flex justify-between shadow-sm fixed top-0 left-0 right-0 z-20">
|
||||||
|
<div>
|
||||||
|
<h1 class="text-2xl font-bold text-primary flex items-center">
|
||||||
|
<i class="fas fa-envelope mr-2"></i>
|
||||||
|
Email Organizer
|
||||||
|
</h1>
|
||||||
|
<p class="text-sm mt-1 text-base-content/70">AI-powered email organization</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
<button class="relative p-2 rounded-full hover:bg-base-300 btn-circle">
|
||||||
|
<i class="fas fa-bell"></i>
|
||||||
|
<span class="badge badge-sm badge-secondary absolute -top-1 -right-1">3</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="relative" x-data="{ open: false }" @click.outside="open = false">
|
||||||
|
<button id="user-menu-button" class="flex items-center space-x-2 p-2 rounded-lg hover:bg-base-300"
|
||||||
|
@click="open = !open">
|
||||||
|
<div class="w-8 h-8 rounded-full bg-primary flex items-center justify-center">
|
||||||
|
<span class="font-semibold text-primary-content">{{ current_user.first_name[0] }}{{
|
||||||
|
current_user.last_name[0] }}</span>
|
||||||
|
</div>
|
||||||
|
<span class="hidden md:inline">{{ current_user.first_name }} {{ current_user.last_name }}</span>
|
||||||
|
<i class="fas fa-chevron-down"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- User Dropdown -->
|
||||||
|
<div id="user-dropdown"
|
||||||
|
class="user-dropdown absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-base-100 z-10"
|
||||||
|
x-show="open">
|
||||||
|
<a href="#" class="block px-4 py-2 text-sm hover:bg-base-300">Profile</a>
|
||||||
|
<a href="#" class="block px-4 py-2 text-sm hover:bg-base-300">Settings</a>
|
||||||
|
<a href="{{ url_for('auth.logout') }}" class="block px-4 py-2 text-sm hover:bg-base-300">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
4
app/templates/partials/modal_holder.html
Normal file
4
app/templates/partials/modal_holder.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<!-- Modal Holder -->
|
||||||
|
<dialog id="modal-holder" x-ref="modal" class="modal">
|
||||||
|
<!-- Modals will be loaded here via HTMX -->
|
||||||
|
</dialog>
|
||||||
44
app/templates/partials/sidebar.html
Normal file
44
app/templates/partials/sidebar.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<div class="sidebar w-64 p-4 flex flex-col bg-base-200 shadow-lg fixed top-16 left-0 bottom-0 z-10">
|
||||||
|
|
||||||
|
<nav class="flex-grow menu bg-transparent rounded-lg">
|
||||||
|
<div class="active">
|
||||||
|
<a class="btn btn-ghost justify-start">
|
||||||
|
<i class="fas fa-folder mr-3 text-primary"></i>
|
||||||
|
Folders
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-ghost justify-start">
|
||||||
|
<i class="fas fa-inbox mr-3 text-secondary"></i>
|
||||||
|
Inbox
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-ghost justify-start">
|
||||||
|
<i class="fas fa-cog mr-3 text-accent"></i>
|
||||||
|
Settings
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-ghost justify-start">
|
||||||
|
<i class="fas fa-chart-bar mr-3 text-info"></i>
|
||||||
|
Analytics
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-ghost justify-start">
|
||||||
|
<i class="fas fa-question-circle mr-3 text-warning"></i>
|
||||||
|
Help
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="mt-auto pt-4 border-t border-base-300">
|
||||||
|
<div>
|
||||||
|
<a href="{{ url_for('auth.logout') }}" class="btn btn-ghost justify-start">
|
||||||
|
<i class="fas fa-sign-out-alt mr-3 text-error"></i>
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user