myCRM/templates/security/password_reset_request.html.twig
olli 3e30d958b3 feat: Implement password reset functionality
- Added PasswordResetController to handle password reset requests and confirmations.
- Created views for password reset request, confirmation, and invalid link scenarios.
- Implemented email sending for password reset requests with security measures.
- Added form validation for password reset confirmation, including password strength requirements.
- Enhanced user experience with success and error messages during the password reset process.
2025-11-11 14:31:40 +01:00

257 lines
9.1 KiB
Twig

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Passwort zurücksetzen - myCRM</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: #f8fafc;
min-height: 100vh;
}
.login-container {
background: #f8fafc;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
min-width: 100vw;
overflow: hidden;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.login-card-wrapper {
border-radius: 56px;
padding: 0.3rem;
background: linear-gradient(180deg, #3B82F6 10%, rgba(33, 150, 243, 0) 30%);
}
.login-card {
width: 100%;
background: #ffffff;
padding: 5rem 2rem;
border-radius: 53px;
}
@media (min-width: 576px) {
.login-card {
padding: 5rem 5rem;
}
}
.login-header {
text-align: center;
margin-bottom: 2rem;
}
.login-logo {
margin-bottom: 2rem;
width: 4rem;
flex-shrink: 0;
margin-left: auto;
margin-right: auto;
}
.login-title {
color: #0f172a;
font-size: 1.875rem;
font-weight: 500;
margin-bottom: 1rem;
margin-top: 0;
}
.login-subtitle {
color: #64748b;
font-weight: 500;
margin: 0;
}
.login-form {
width: 100%;
}
@media (min-width: 768px) {
.login-form {
width: 30rem;
}
}
.form-field {
margin-bottom: 2rem;
}
.form-field label {
display: block;
color: #0f172a;
font-weight: 500;
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.p-inputtext {
width: 100%;
padding: 0.75rem;
font-size: 1rem;
color: #0f172a;
background: #ffffff;
border: 1px solid #cbd5e1;
border-radius: 0.375rem;
transition: border-color 0.2s, box-shadow 0.2s;
outline: 0 none;
}
.p-inputtext:hover {
border-color: #94a3b8;
}
.p-inputtext:focus {
border-color: #3B82F6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
}
.p-button {
width: 100%;
padding: 0.75rem 1.25rem;
font-size: 1rem;
font-weight: 500;
color: #ffffff;
background: #3B82F6;
border: 1px solid #3B82F6;
border-radius: 0.375rem;
cursor: pointer;
transition: background 0.2s;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
text-decoration: none;
outline: 0 none;
}
.p-button:hover {
background: #2563eb;
border-color: #2563eb;
}
.p-message {
padding: 1rem 1.25rem;
border-radius: 0.375rem;
margin-bottom: 1.5rem;
font-size: 0.875rem;
display: flex;
align-items: flex-start;
gap: 0.75rem;
}
.p-message-error {
background: #fef2f2;
border: 1px solid #fecaca;
color: #dc2626;
}
.p-message-success {
background: #f0fdf4;
border: 1px solid #bbf7d0;
color: #16a34a;
}
.p-message-icon {
font-size: 1.125rem;
flex-shrink: 0;
}
.back-link {
text-align: center;
margin-top: 1.5rem;
}
.back-link a {
color: #3B82F6;
text-decoration: none;
font-weight: 500;
}
.back-link a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-wrapper">
<div class="login-card-wrapper">
<div class="login-card">
<div class="login-header">
<svg viewBox="0 0 54 40" fill="none" xmlns="http://www.w3.org/2000/svg" class="login-logo">
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.1637 19.2467C17.1566 19.4033 17.1529 19.561 17.1529 19.7194C17.1529 25.3503 21.7203 29.915 27.3546 29.915C32.9887 29.915 37.5561 25.3503 37.5561 19.7194C37.5561 19.5572 37.5524 19.3959 37.5449 19.2355C38.5617 19.0801 39.5759 18.9013 40.5867 18.6994L40.6926 18.6782C40.7191 19.0218 40.7326 19.369 40.7326 19.7194C40.7326 27.1036 34.743 33.0896 27.3546 33.0896C19.966 33.0896 13.9765 27.1036 13.9765 19.7194C13.9765 19.374 13.9896 19.0316 14.0154 18.6927L14.0486 18.6994C15.0837 18.9062 16.1223 19.0886 17.1637 19.2467ZM33.3284 11.4538C31.6493 10.2396 29.5855 9.52381 27.3546 9.52381C25.1195 9.52381 23.0524 10.2421 21.3717 11.4603C20.0078 11.3232 18.6475 11.1387 17.2933 10.907C19.7453 8.11308 23.3438 6.34921 27.3546 6.34921C31.36 6.34921 34.9543 8.10844 37.4061 10.896C36.0521 11.1292 34.692 11.3152 33.3284 11.4538ZM43.826 18.0518C43.881 18.6003 43.9091 19.1566 43.9091 19.7194C43.9091 28.8568 36.4973 36.2642 27.3546 36.2642C18.2117 36.2642 10.8 28.8568 10.8 19.7194C10.8 19.1615 10.8276 18.61 10.8816 18.0663L7.75383 17.4411C7.66775 18.1886 7.62354 18.9488 7.62354 19.7194C7.62354 30.6102 16.4574 39.4388 27.3546 39.4388C38.2517 39.4388 47.0855 30.6102 47.0855 19.7194C47.0855 18.9439 47.0407 18.1789 46.9536 17.4267L43.826 18.0518ZM44.2613 9.54743L40.9084 10.2176C37.9134 5.95821 32.9593 3.1746 27.3546 3.1746C21.7442 3.1746 16.7856 5.96385 13.7915 10.2305L10.4399 9.56057C13.892 3.83178 20.1756 0 27.3546 0C34.5281 0 40.8075 3.82591 44.2613 9.54743Z" fill="#3B82F6"/>
</svg>
<h1 class="login-title">Passwort zurücksetzen</h1>
<p class="login-subtitle">Geben Sie Ihre E-Mail-Adresse ein</p>
</div>
<div class="login-form">
{% if email_sent %}
<div class="p-message p-message-success">
<span class="p-message-icon">✓</span>
<div>
<strong>E-Mail versendet!</strong><br>
Falls ein Account mit dieser E-Mail-Adresse existiert, haben Sie eine E-Mail mit weiteren Anweisungen erhalten.
Bitte überprüfen Sie auch Ihren Spam-Ordner.
</div>
</div>
<div class="back-link">
<a href="{{ path('app_login') }}">← Zurück zum Login</a>
</div>
{% else %}
{% if error %}
<div class="p-message p-message-error">
<span class="p-message-icon">✕</span>
<div>{{ error }}</div>
</div>
{% endif %}
<form method="post">
<div class="form-field">
<label for="email">E-Mail-Adresse</label>
<input
type="email"
name="email"
id="email"
class="p-inputtext"
placeholder="ihre@email.de"
required
autofocus
>
</div>
<button class="p-button" type="submit">
<span>Link zum Zurücksetzen senden</span>
</button>
</form>
<div class="back-link">
<a href="{{ path('app_login') }}">← Zurück zum Login</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</body>
</html>