HTML email for new student and lecturer
This commit is contained in:
parent
3d8baebf74
commit
c432e57709
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"[html]": {
|
// "[html]": {
|
||||||
"editor.formatOnSave": false
|
// "editor.formatOnSave": false
|
||||||
},
|
// },
|
||||||
"liveSassCompile.settings.includeItems": ["/**/static/scss/style.scss"],
|
"liveSassCompile.settings.includeItems": ["/**/static/scss/style.scss"],
|
||||||
"liveSassCompile.settings.formats": [
|
"liveSassCompile.settings.formats": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,3 +3,12 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
class AccountsConfig(AppConfig):
|
class AccountsConfig(AppConfig):
|
||||||
name = "accounts"
|
name = "accounts"
|
||||||
|
|
||||||
|
def ready(self) -> None:
|
||||||
|
from django.db.models.signals import post_save
|
||||||
|
from .models import User
|
||||||
|
from .signals import post_save_account_receiver
|
||||||
|
|
||||||
|
post_save.connect(post_save_account_receiver, sender=User)
|
||||||
|
|
||||||
|
return super().ready()
|
||||||
|
|||||||
@ -1,6 +1,3 @@
|
|||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.contrib.auth.forms import (
|
from django.contrib.auth.forms import (
|
||||||
@ -10,7 +7,6 @@ from django.contrib.auth.forms import (
|
|||||||
from django.contrib.auth.forms import PasswordResetForm
|
from django.contrib.auth.forms import PasswordResetForm
|
||||||
from course.models import Program
|
from course.models import Program
|
||||||
from .models import User, Student, Parent, RELATION_SHIP, LEVEL, GENDERS
|
from .models import User, Student, Parent, RELATION_SHIP, LEVEL, GENDERS
|
||||||
from .tasks import send_new_student_email, send_new_lecturer_email
|
|
||||||
|
|
||||||
|
|
||||||
class StaffAddForm(UserCreationForm):
|
class StaffAddForm(UserCreationForm):
|
||||||
@ -118,24 +114,9 @@ class StaffAddForm(UserCreationForm):
|
|||||||
user.address = self.cleaned_data.get("address")
|
user.address = self.cleaned_data.get("address")
|
||||||
user.email = self.cleaned_data.get("email")
|
user.email = self.cleaned_data.get("email")
|
||||||
|
|
||||||
# Generate a username
|
|
||||||
registration_date = datetime.now().strftime("%Y")
|
|
||||||
total_lecturers_count = User.objects.filter(is_lecturer=True).count()
|
|
||||||
generated_username = (
|
|
||||||
f"{settings.LECTURER_ID_PREFIX}-{registration_date}-{total_lecturers_count}"
|
|
||||||
)
|
|
||||||
# Generate a password
|
|
||||||
generated_password = User.objects.make_random_password()
|
|
||||||
|
|
||||||
user.username = generated_username
|
|
||||||
user.set_password(generated_password)
|
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
# Send email with the generated credentials
|
|
||||||
send_new_lecturer_email.delay(user.pk, generated_password)
|
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
@ -272,18 +253,6 @@ class StudentAddForm(UserCreationForm):
|
|||||||
user.address = self.cleaned_data.get("address")
|
user.address = self.cleaned_data.get("address")
|
||||||
user.email = self.cleaned_data.get("email")
|
user.email = self.cleaned_data.get("email")
|
||||||
|
|
||||||
# Generate a username based on first and last name and registration date
|
|
||||||
registration_date = datetime.now().strftime("%Y")
|
|
||||||
total_students_count = Student.objects.count()
|
|
||||||
generated_username = (
|
|
||||||
f"{settings.STUDENT_ID_PREFIX}-{registration_date}-{total_students_count}"
|
|
||||||
)
|
|
||||||
# Generate a password
|
|
||||||
generated_password = User.objects.make_random_password()
|
|
||||||
|
|
||||||
user.username = generated_username
|
|
||||||
user.set_password(generated_password)
|
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
user.save()
|
user.save()
|
||||||
Student.objects.create(
|
Student.objects.create(
|
||||||
@ -292,9 +261,6 @@ class StudentAddForm(UserCreationForm):
|
|||||||
program=self.cleaned_data.get("program"),
|
program=self.cleaned_data.get("program"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Send email with the generated credentials
|
|
||||||
send_new_student_email.delay(user.pk, generated_password)
|
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
from .tasks import send_new_student_email, send_new_lecturer_email
|
||||||
|
from .utils import generate_student_credentials, generate_lecturer_credentials
|
||||||
|
|
||||||
|
|
||||||
|
def post_save_account_receiver(sender, instance=None, created=False, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Send email notification
|
||||||
|
"""
|
||||||
|
if created:
|
||||||
|
if instance.is_student:
|
||||||
|
username, password = generate_student_credentials()
|
||||||
|
instance.username = username
|
||||||
|
instance.set_password(password)
|
||||||
|
instance.save()
|
||||||
|
# Send email with the generated credentials
|
||||||
|
send_new_student_email.delay(instance.pk, password)
|
||||||
|
|
||||||
|
if instance.is_lecturer:
|
||||||
|
username, password = generate_lecturer_credentials()
|
||||||
|
instance.username = username
|
||||||
|
instance.set_password(password)
|
||||||
|
instance.save()
|
||||||
|
# Send email with the generated credentials
|
||||||
|
send_new_lecturer_email.delay(instance.pk, password)
|
||||||
@ -1,31 +1,25 @@
|
|||||||
import time
|
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from django.conf import settings
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.mail import send_mail
|
from core.utils import send_html_email
|
||||||
|
|
||||||
|
|
||||||
def send_email(user, subject, msg):
|
|
||||||
send_mail(
|
|
||||||
subject,
|
|
||||||
msg,
|
|
||||||
settings.EMAIL_FROM_ADDRESS,
|
|
||||||
[user.email],
|
|
||||||
fail_silently=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def send_new_student_email(user_pk, password):
|
def send_new_student_email(user_pk, password):
|
||||||
user = get_user_model().objects.get(pk=user_pk)
|
user = get_user_model().objects.get(pk=user_pk)
|
||||||
subject = "Your Dj LMS account credentials"
|
send_html_email(
|
||||||
msg = f"Dear Student {user.first_name},\n\nHere are the login credentials for your DJ LMS account.\n\nYour ID: {user.username}\nYour password: {password}\n\nBe sure to change your password for security."
|
subject="Your Dj LMS account confirmation and credentials",
|
||||||
send_email(user, subject, msg)
|
recipient_list=[user.email],
|
||||||
|
template="accounts/email/new_student_account_confirmation.html",
|
||||||
|
context={"user": user, "password": password},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def send_new_lecturer_email(user_pk, password):
|
def send_new_lecturer_email(user_pk, password):
|
||||||
user = get_user_model().objects.get(pk=user_pk)
|
user = get_user_model().objects.get(pk=user_pk)
|
||||||
subject = "Your Dj LMS account credentials"
|
send_html_email(
|
||||||
msg = f"Dear Lecturer {user.first_name},\n\nHere are the login credentials for your DJ LMS account.\n\nYour ID: {user.username}\nYour password: {password}\n\nBe sure to change your password for security."
|
subject="Your Dj LMS account confirmation and credentials",
|
||||||
send_email(user, subject, msg)
|
recipient_list=[user.email],
|
||||||
|
template="accounts/email/new_student_account_confirmation.html",
|
||||||
|
context={"user": user, "password": password},
|
||||||
|
)
|
||||||
|
|||||||
29
accounts/utils.py
Normal file
29
accounts/utils.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
def generate_password():
|
||||||
|
return get_user_model().objects.make_random_password()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_student_id():
|
||||||
|
# Generate a username based on first and last name and registration date
|
||||||
|
registered_year = datetime.now().strftime("%Y")
|
||||||
|
students_count = get_user_model().objects.filter(is_student=True).count()
|
||||||
|
return f"{settings.STUDENT_ID_PREFIX}-{registered_year}-{students_count}"
|
||||||
|
|
||||||
|
|
||||||
|
def generate_lecturer_id():
|
||||||
|
# Generate a username based on first and last name and registration date
|
||||||
|
registered_year = datetime.now().strftime("%Y")
|
||||||
|
lecturers_count = get_user_model().objects.filter(is_lecturer=True).count()
|
||||||
|
return f"{settings.LECTURER_ID_PREFIX}-{registered_year}-{lecturers_count}"
|
||||||
|
|
||||||
|
|
||||||
|
def generate_student_credentials():
|
||||||
|
return generate_student_id(), generate_password()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_lecturer_credentials():
|
||||||
|
return generate_lecturer_id(), generate_password()
|
||||||
32
core/utils.py
Normal file
32
core/utils.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from django.core.mail import send_mail
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from django.utils.html import strip_tags
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
def send_email(user, subject, msg):
|
||||||
|
send_mail(
|
||||||
|
subject,
|
||||||
|
msg,
|
||||||
|
settings.EMAIL_FROM_ADDRESS,
|
||||||
|
[user.email],
|
||||||
|
fail_silently=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def send_html_email(subject, recipient_list, template, context):
|
||||||
|
"""A function responsible for sending HTML email"""
|
||||||
|
# Render the HTML template
|
||||||
|
html_message = render_to_string(template, context)
|
||||||
|
|
||||||
|
# Generate plain text version of the email (optional)
|
||||||
|
plain_message = strip_tags(html_message)
|
||||||
|
|
||||||
|
# Send the email
|
||||||
|
send_mail(
|
||||||
|
subject,
|
||||||
|
plain_message,
|
||||||
|
settings.EMAIL_FROM_ADDRESS,
|
||||||
|
recipient_list,
|
||||||
|
html_message=html_message,
|
||||||
|
)
|
||||||
303
templates/accounts/email/new_lecturer_account_confirmation.html
Executable file
303
templates/accounts/email/new_lecturer_account_confirmation.html
Executable file
@ -0,0 +1,303 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Account Confirmation</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--padding-base: 0.5rem;
|
||||||
|
--primary: #4caf50;
|
||||||
|
--primary-dark: #45a049;
|
||||||
|
--warning: #ffcb00;
|
||||||
|
--warning-dark: #edbe02;
|
||||||
|
--light: #ffffff;
|
||||||
|
--gmail-primary: #ebf0fb;
|
||||||
|
--gmail-secondary: #f6f9fd;
|
||||||
|
--body-color: var(--gmail-primary);
|
||||||
|
--grey-100: #e9e9e9;
|
||||||
|
--grey-200: #cfcfcf;
|
||||||
|
--grey-300: #9d9d9d;
|
||||||
|
--grey-400: #888888;
|
||||||
|
--grey-500: #555555;
|
||||||
|
--dark: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset default styling */
|
||||||
|
body,
|
||||||
|
p,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3
|
||||||
|
|
||||||
|
/* h4, */
|
||||||
|
/* h5, */
|
||||||
|
/* h6 */ {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
color: #012481;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #005aeb;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #46528f;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: #ebf0fb;
|
||||||
|
border-bottom: 1px solid #cfcfcf;
|
||||||
|
padding: 0.5rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer p {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer p,
|
||||||
|
.footer a {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 600px;
|
||||||
|
max-width: 600px !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #cfcfcf;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
padding: 1.5rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-5 {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-4 {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-3 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-1 {
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-5 {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-4 {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-3 {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-2 {
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-2 {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps-1 {
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-0 {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-3 {
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-2 {
|
||||||
|
padding-top: 0.6rem;
|
||||||
|
padding-bottom: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-5 {
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.px-5 {
|
||||||
|
padding-left: 40px;
|
||||||
|
padding-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-0 {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fw-400 {
|
||||||
|
font-weight: 400 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lh-1 {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-muted {
|
||||||
|
color: rgba(70, 82, 143, 0.5) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
border-bottom: 1px solid #cfcfcf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #e9e9e9;
|
||||||
|
color: #333333;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #4caf50;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-warning {
|
||||||
|
background-color: #ffcb00;
|
||||||
|
color: #333333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-warning:hover {
|
||||||
|
background-color: #edbe02;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uppercase {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body
|
||||||
|
style="
|
||||||
|
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
color: #46528f;
|
||||||
|
background-color: #ebf0fb;
|
||||||
|
padding: 20px;
|
||||||
|
line-height: 1.4;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="container">
|
||||||
|
<div class="card">
|
||||||
|
<div class="header">
|
||||||
|
<h2 class="text-muted lh-1">Dj LMS</h2>
|
||||||
|
<p class="small text-muted fw-400 lh-1 m-0">
|
||||||
|
Your learning management system
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<h1 class="mb-5">🚀 Confirm your account</h1>
|
||||||
|
<h4>Dear <b>{{ user.get_full_name }}</b>,</h4>
|
||||||
|
<p>
|
||||||
|
A new lecturer account with ID of <b>{user.username}</b> has been
|
||||||
|
created for you. <br />
|
||||||
|
You're receiving this e-mail because the Dj-LMS admin has given your
|
||||||
|
e-mail address to register an account on djlms.com. <br />
|
||||||
|
</p>
|
||||||
|
<h5>Login credentials for your DJ LMS account:</h5>
|
||||||
|
<ul>
|
||||||
|
<li>ID: {user.username}</li>
|
||||||
|
<li>Your password: {password}</li>
|
||||||
|
</ul>
|
||||||
|
<p>To secure your account be sure to change your password.</p>
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
href="http://localhost:3000/auth/confirm-email?key={{ key }}"
|
||||||
|
class="btn btn-primary"
|
||||||
|
>Confirm Email and Login</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p class="text-muted small">
|
||||||
|
<mark
|
||||||
|
>⚠ If you think this email should not come to you, you can simply
|
||||||
|
ignore it.</mark
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<p>Sincerely - djlms team!</p>
|
||||||
|
<p>
|
||||||
|
For any inquiries or assistance, please contact our support team:
|
||||||
|
</p>
|
||||||
|
<p>Email: <a href="mailto:support@djlms.com">support@djlms.com</a></p>
|
||||||
|
<p>Phone: <a href="tel:251900000000">+(251) 90-000-0000</a></p>
|
||||||
|
<p>
|
||||||
|
© 2023 <a href="djlms.com">djlms.com</a> | All rights reserved.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
303
templates/accounts/email/new_student_account_confirmation.html
Executable file
303
templates/accounts/email/new_student_account_confirmation.html
Executable file
@ -0,0 +1,303 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Account Confirmation</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--padding-base: 0.5rem;
|
||||||
|
--primary: #4caf50;
|
||||||
|
--primary-dark: #45a049;
|
||||||
|
--warning: #ffcb00;
|
||||||
|
--warning-dark: #edbe02;
|
||||||
|
--light: #ffffff;
|
||||||
|
--gmail-primary: #ebf0fb;
|
||||||
|
--gmail-secondary: #f6f9fd;
|
||||||
|
--body-color: var(--gmail-primary);
|
||||||
|
--grey-100: #e9e9e9;
|
||||||
|
--grey-200: #cfcfcf;
|
||||||
|
--grey-300: #9d9d9d;
|
||||||
|
--grey-400: #888888;
|
||||||
|
--grey-500: #555555;
|
||||||
|
--dark: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset default styling */
|
||||||
|
body,
|
||||||
|
p,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3
|
||||||
|
|
||||||
|
/* h4, */
|
||||||
|
/* h5, */
|
||||||
|
/* h6 */ {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
color: #012481;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #005aeb;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #46528f;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: #ebf0fb;
|
||||||
|
border-bottom: 1px solid #cfcfcf;
|
||||||
|
padding: 0.5rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer p {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer p,
|
||||||
|
.footer a {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 600px;
|
||||||
|
max-width: 600px !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #cfcfcf;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
padding: 1.5rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-5 {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-4 {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-3 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-1 {
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-5 {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-4 {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-3 {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-2 {
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-2 {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps-1 {
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-0 {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-3 {
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-2 {
|
||||||
|
padding-top: 0.6rem;
|
||||||
|
padding-bottom: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-5 {
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.px-5 {
|
||||||
|
padding-left: 40px;
|
||||||
|
padding-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-0 {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fw-400 {
|
||||||
|
font-weight: 400 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lh-1 {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-muted {
|
||||||
|
color: rgba(70, 82, 143, 0.5) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
border-bottom: 1px solid #cfcfcf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #e9e9e9;
|
||||||
|
color: #333333;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #4caf50;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-warning {
|
||||||
|
background-color: #ffcb00;
|
||||||
|
color: #333333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-warning:hover {
|
||||||
|
background-color: #edbe02;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uppercase {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body
|
||||||
|
style="
|
||||||
|
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
color: #46528f;
|
||||||
|
background-color: #ebf0fb;
|
||||||
|
padding: 20px;
|
||||||
|
line-height: 1.4;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="container">
|
||||||
|
<div class="card">
|
||||||
|
<div class="header">
|
||||||
|
<h2 class="text-muted lh-1">Dj LMS</h2>
|
||||||
|
<p class="small text-muted fw-400 lh-1 m-0">
|
||||||
|
Your learning management system
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<h1 class="mb-5">🚀 Confirm your account</h1>
|
||||||
|
<h4>Dear <b>{{ user.get_full_name }}</b>,</h4>
|
||||||
|
<p>
|
||||||
|
A new student account with ID of <b>{user.username}</b> has been
|
||||||
|
created for you. <br />
|
||||||
|
You're receiving this e-mail because the Dj-LMS admin has given your
|
||||||
|
e-mail address to register an account on djlms.com. <br />
|
||||||
|
</p>
|
||||||
|
<h5>Login credentials for your DJ LMS account:</h5>
|
||||||
|
<ul>
|
||||||
|
<li>ID: {user.username}</li>
|
||||||
|
<li>Your password: {password}</li>
|
||||||
|
</ul>
|
||||||
|
<p>To secure your account be sure to change your password.</p>
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
href="http://localhost:3000/auth/confirm-email?key={{ key }}"
|
||||||
|
class="btn btn-primary"
|
||||||
|
>Confirm Email and Login</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p class="text-muted small">
|
||||||
|
<mark
|
||||||
|
>⚠ If you think this email should not come to you, you can simply
|
||||||
|
ignore it.</mark
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<p>Sincerely - djlms team!</p>
|
||||||
|
<p>
|
||||||
|
For any inquiries or assistance, please contact our support team:
|
||||||
|
</p>
|
||||||
|
<p>Email: <a href="mailto:support@djlms.com">support@djlms.com</a></p>
|
||||||
|
<p>Phone: <a href="tel:251900000000">+(251) 90-000-0000</a></p>
|
||||||
|
<p>
|
||||||
|
© 2023 <a href="djlms.com">djlms.com</a> | All rights reserved.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user