Referral Rewards V1
This commit is contained in:
parent
ce20f7b1f5
commit
82aa5f8851
Binary file not shown.
@ -43,6 +43,9 @@ CSRF_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_SAMESITE = "None"
|
||||
CSRF_COOKIE_SAMESITE = "None"
|
||||
|
||||
# IMPORTANT for reverse proxy (Apache) to correctly identify HTTPS
|
||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
|
||||
|
||||
@ -65,6 +68,7 @@ MIDDLEWARE = [
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'core.middleware.ReferralMiddleware',
|
||||
# Disable X-Frame-Options middleware to allow Flatlogic preview iframes.
|
||||
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
@ -156,13 +160,13 @@ STATICFILES_DIRS = [
|
||||
]
|
||||
|
||||
# Email
|
||||
EMAIL_HOST = os.getenv("EMAIL_HOST", "127.0.0.1")
|
||||
EMAIL_PORT = int(os.getenv("EMAIL_PORT", "587"))
|
||||
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER", "")
|
||||
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD", "")
|
||||
EMAIL_USE_TLS = os.getenv("EMAIL_USE_TLS", "true").lower() == "true"
|
||||
EMAIL_USE_SSL = os.getenv("EMAIL_USE_SSL", "false").lower() == "true"
|
||||
DEFAULT_FROM_EMAIL = os.getenv("DEFAULT_FROM_EMAIL", "no-reply@example.com")
|
||||
EMAIL_HOST = os.getenv("SMTP_HOST", "127.0.0.1")
|
||||
EMAIL_PORT = int(os.getenv("SMTP_PORT", "587"))
|
||||
EMAIL_HOST_USER = os.getenv("SMTP_USER", "")
|
||||
EMAIL_HOST_PASSWORD = os.getenv("SMTP_PASS", "")
|
||||
EMAIL_USE_TLS = os.getenv("SMTP_SECURE", "tls").lower() == "tls"
|
||||
EMAIL_USE_SSL = os.getenv("SMTP_SECURE", "tls").lower() == "ssl"
|
||||
DEFAULT_FROM_EMAIL = os.getenv("MAIL_FROM", "no-reply@example.com")
|
||||
CONTACT_EMAIL_TO = [
|
||||
item.strip()
|
||||
for item in os.getenv("CONTACT_EMAIL_TO", DEFAULT_FROM_EMAIL).split(",")
|
||||
@ -186,4 +190,4 @@ if EMAIL_USE_SSL:
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
LOGIN_REDIRECT_URL = 'dashboard'
|
||||
LOGOUT_REDIRECT_URL = 'home'
|
||||
LOGOUT_REDIRECT_URL = 'home'
|
||||
Binary file not shown.
BIN
core/__pycache__/middleware.cpython-311.pyc
Normal file
BIN
core/__pycache__/middleware.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -20,3 +20,6 @@ class SignupForm(UserCreationForm):
|
||||
if commit:
|
||||
user.save()
|
||||
return user
|
||||
|
||||
class ResendActivationForm(forms.Form):
|
||||
email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Enter your email'}))
|
||||
0
core/management/__init__.py
Normal file
0
core/management/__init__.py
Normal file
BIN
core/management/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
core/management/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
0
core/management/commands/__init__.py
Normal file
0
core/management/commands/__init__.py
Normal file
BIN
core/management/commands/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
core/management/commands/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
48
core/management/commands/resend_activation.py
Normal file
48
core/management/commands/resend_activation.py
Normal file
@ -0,0 +1,48 @@
|
||||
import os
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.utils.encoding import force_bytes
|
||||
from django.utils.http import urlsafe_base64_encode
|
||||
from django.template.loader import render_to_string
|
||||
from django.core.mail import EmailMessage
|
||||
from django.conf import settings
|
||||
from core.tokens import account_activation_token
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Resend activation email to a specific user'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('username', type=str)
|
||||
parser.add_argument('--domain', type=str, default=os.getenv("HOST_FQDN", "localhost:8000"))
|
||||
|
||||
def handle(self, *args, **args_options):
|
||||
username = args_options['username']
|
||||
domain = args_options['domain']
|
||||
|
||||
try:
|
||||
user = User.objects.get(username=username)
|
||||
if user.is_active:
|
||||
self.stdout.write(self.style.WARNING(f"User '{username}' is already active."))
|
||||
return
|
||||
|
||||
mail_subject = 'Activate your Referral Rewards account.'
|
||||
message = render_to_string('core/emails/activation_email.html', {
|
||||
'user': user,
|
||||
'domain': domain,
|
||||
'protocol': 'https', # Defaulting to https for Flatlogic
|
||||
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
|
||||
'token': account_activation_token.make_token(user),
|
||||
})
|
||||
|
||||
email = EmailMessage(
|
||||
mail_subject, message, to=[user.email]
|
||||
)
|
||||
email.send()
|
||||
self.stdout.write(self.style.SUCCESS(f"Successfully sent activation email to '{username}' ({user.email})."))
|
||||
|
||||
except User.DoesNotExist:
|
||||
self.stdout.write(self.style.ERROR(f"User '{username}' does not exist."))
|
||||
except Exception as e:
|
||||
self.stdout.write(self.style.ERROR(f"Error sending email: {str(e)}"))
|
||||
11
core/middleware.py
Normal file
11
core/middleware.py
Normal file
@ -0,0 +1,11 @@
|
||||
class ReferralMiddleware:
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
ref_code = request.GET.get('ref')
|
||||
if ref_code:
|
||||
request.session['ref'] = ref_code
|
||||
|
||||
response = self.get_response(request)
|
||||
return response
|
||||
33
core/migrations/0002_profile_referred_by_referral.py
Normal file
33
core/migrations/0002_profile_referred_by_referral.py
Normal file
@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.2.7 on 2026-02-28 22:03
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='profile',
|
||||
name='referred_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='referrals_made', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Referral',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('referral_code', models.CharField(max_length=20)),
|
||||
('status', models.CharField(choices=[('pending', 'Pending'), ('successful', 'Successful'), ('rewarded', 'Rewarded')], default='pending', max_length=20)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('completed_at', models.DateTimeField(blank=True, null=True)),
|
||||
('referred_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='received_referrals', to=settings.AUTH_USER_MODEL)),
|
||||
('referrer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sent_referrals', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
Binary file not shown.
@ -7,6 +7,7 @@ import uuid
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
|
||||
referral_code = models.CharField(max_length=20, unique=True, blank=True)
|
||||
referred_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='referrals_made')
|
||||
points = models.IntegerField(default=0)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@ -18,6 +19,21 @@ class Profile(models.Model):
|
||||
self.referral_code = str(uuid.uuid4()).replace('-', '')[:8].upper()
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
class Referral(models.Model):
|
||||
referrer = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sent_referrals')
|
||||
referred_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='received_referrals', null=True, blank=True)
|
||||
referral_code = models.CharField(max_length=20)
|
||||
status = models.CharField(max_length=20, default='pending', choices=[
|
||||
('pending', 'Pending'),
|
||||
('successful', 'Successful'),
|
||||
('rewarded', 'Rewarded'),
|
||||
])
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
completed_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"Referral from {self.referrer.username} (Code: {self.referral_code})"
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def create_user_profile(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
|
||||
@ -25,9 +25,9 @@
|
||||
<div class="card h-100 border-0 shadow-sm p-4 rounded-4 bg-white text-center">
|
||||
<p class="text-muted small text-uppercase fw-bold mb-2">Total Points</p>
|
||||
<h3 class="display-5 fw-bold text-primary mb-0">{{ profile.points }}</h3>
|
||||
<p class="text-muted mt-2 mb-0">Points to next reward: 100</p>
|
||||
<p class="text-muted mt-2 mb-0">Total successful referrals: {{ referrals.count }}</p>
|
||||
<div class="progress mt-3" style="height: 8px;">
|
||||
<div class="progress-bar bg-primary" style="width: {{ profile.points|default:0 }}%;"></div>
|
||||
<div class="progress-bar bg-primary" style="width: {{ profile.points }}%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -36,16 +36,53 @@
|
||||
<div class="col-lg-8">
|
||||
<div class="card h-100 border-0 shadow-sm p-4 rounded-4 bg-white">
|
||||
<h4 class="mb-4">Your Referral Link</h4>
|
||||
<p class="text-muted mb-4">Share this code with your friends and earn points when they sign up!</p>
|
||||
<p class="text-muted mb-4">Share this link with your friends and earn points when they sign up and activate their account!</p>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" id="referralCode" class="form-control form-control-lg bg-light border-0" value="{{ profile.referral_code }}" readonly>
|
||||
<button class="btn btn-primary px-4" type="button" onclick="copyCode()">Copy Code</button>
|
||||
<input type="text" id="referralLink" class="form-control form-control-lg bg-light border-0" value="{{ referral_link }}" readonly>
|
||||
<button class="btn btn-primary px-4" type="button" onclick="copyLink()">Copy Link</button>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-3 mt-4">
|
||||
<button class="btn btn-outline-primary flex-fill py-2">Share on Twitter</button>
|
||||
<button class="btn btn-outline-primary flex-fill py-2">Share on WhatsApp</button>
|
||||
<a href="https://twitter.com/intent/tweet?text=Join%20me%20on%20Referral%20Rewards%21%20{{ referral_link }}" target="_blank" class="btn btn-outline-primary flex-fill py-2">Share on Twitter</a>
|
||||
<a href="https://wa.me/?text=Join%20me%20on%20Referral%20Rewards%21%20{{ referral_link }}" target="_blank" class="btn btn-outline-primary flex-fill py-2">Share on WhatsApp</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent Referrals -->
|
||||
<div class="col-12 mt-4">
|
||||
<h4 class="mb-4">Successful Referrals</h4>
|
||||
<div class="card border-0 shadow-sm rounded-4 overflow-hidden bg-white">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th class="px-4 py-3 border-0">Username</th>
|
||||
<th class="px-4 py-3 border-0 text-center">Date Joined</th>
|
||||
<th class="px-4 py-3 border-0 text-center">Status</th>
|
||||
<th class="px-4 py-3 border-0 text-end">Reward</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for referral in referrals %}
|
||||
<tr>
|
||||
<td class="px-4 py-3 border-0">{{ referral.referred_user.username }}</td>
|
||||
<td class="px-4 py-3 border-0 text-center text-muted">{{ referral.completed_at|date:"M d, Y" }}</td>
|
||||
<td class="px-4 py-3 border-0 text-center">
|
||||
<span class="badge bg-success rounded-pill px-3">{{ referral.get_status_display }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 border-0 text-end fw-bold text-primary">+10 Points</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="4" class="px-4 py-5 text-center text-muted">
|
||||
No referrals yet. Share your link to start earning rewards!
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -96,8 +133,8 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyCode() {
|
||||
var copyText = document.getElementById("referralCode");
|
||||
function copyLink() {
|
||||
var copyText = document.getElementById("referralLink");
|
||||
copyText.select();
|
||||
copyText.setSelectionRange(0, 99999);
|
||||
navigator.clipboard.writeText(copyText.value);
|
||||
@ -115,4 +152,4 @@
|
||||
}, 2000);
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@ -32,7 +32,8 @@
|
||||
<input type="password" name="password" class="form-control" id="id_password" placeholder="Password" required>
|
||||
</div>
|
||||
|
||||
<div class="text-end mb-4">
|
||||
<div class="d-flex justify-content-between mb-4">
|
||||
<a href="{% url 'resend_activation' %}" class="text-decoration-none small fw-bold">Resend activation?</a>
|
||||
<a href="{% url 'password_reset' %}" class="text-decoration-none small fw-bold">Forgot password?</a>
|
||||
</div>
|
||||
|
||||
|
||||
45
core/templates/core/resend_activation.html
Normal file
45
core/templates/core/resend_activation.html
Normal file
@ -0,0 +1,45 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Resend Activation - Referral Rewards{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5 mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-5">
|
||||
<div class="card border-0 shadow-lg p-4 p-md-5 rounded-4">
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="mb-3">Resend Activation</h2>
|
||||
<p class="text-muted">Enter your email to receive a new activation link.</p>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.non_field_errors %}
|
||||
<div class="alert alert-danger">
|
||||
{% for error in form.non_field_errors %}
|
||||
{{ error }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="{{ form.email.id_for_label }}" class="form-label fw-600">Email Address</label>
|
||||
{{ form.email }}
|
||||
{% if form.email.errors %}
|
||||
<div class="text-danger small mt-1">
|
||||
{{ form.email.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100 py-3 mb-3">Resend Activation Link</button>
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<a href="{% url 'login' %}" class="text-decoration-none small fw-bold">Back to Login</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -6,6 +6,7 @@ urlpatterns = [
|
||||
path("", views.home, name="home"),
|
||||
path("signup/", views.signup, name="signup"),
|
||||
path("activate/<uidb64>/<token>/", views.activate, name="activate"),
|
||||
path("resend-activation/", views.resend_activation, name="resend_activation"),
|
||||
path("dashboard/", views.dashboard, name="dashboard"),
|
||||
path("login/", auth_views.LoginView.as_view(template_name='core/login.html'), name="login"),
|
||||
path("logout/", views.logout_view, name="logout"),
|
||||
|
||||
119
core/views.py
119
core/views.py
@ -7,13 +7,30 @@ from django.utils.encoding import force_bytes, force_str
|
||||
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
|
||||
from django.template.loader import render_to_string
|
||||
from django.core.mail import EmailMessage
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import Profile
|
||||
from .forms import SignupForm
|
||||
from .models import Profile, Referral
|
||||
from .forms import SignupForm, ResendActivationForm
|
||||
from .tokens import account_activation_token
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
def send_activation_email(request, user):
|
||||
current_site = get_current_site(request)
|
||||
mail_subject = 'Activate your Referral Rewards account.'
|
||||
message = render_to_string('core/emails/activation_email.html', {
|
||||
'user': user,
|
||||
'domain': current_site.domain,
|
||||
'protocol': 'https' if request.is_secure() else 'http',
|
||||
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
|
||||
'token': account_activation_token.make_token(user),
|
||||
})
|
||||
to_email = user.email
|
||||
email = EmailMessage(
|
||||
mail_subject, message, to=[to_email]
|
||||
)
|
||||
return email.send()
|
||||
|
||||
def home(request):
|
||||
if request.user.is_authenticated:
|
||||
return redirect('dashboard')
|
||||
@ -29,22 +46,30 @@ def signup(request):
|
||||
user.is_active = False
|
||||
user.save()
|
||||
|
||||
# Referral logic
|
||||
ref_code = request.session.get('ref')
|
||||
if ref_code:
|
||||
try:
|
||||
referrer_profile = Profile.objects.get(referral_code=ref_code)
|
||||
referrer = referrer_profile.user
|
||||
|
||||
# Update user's profile with referrer
|
||||
user.profile.referred_by = referrer
|
||||
user.profile.save()
|
||||
|
||||
# Create Referral record
|
||||
Referral.objects.create(
|
||||
referrer=referrer,
|
||||
referred_user=user,
|
||||
referral_code=ref_code,
|
||||
status='pending'
|
||||
)
|
||||
except Profile.DoesNotExist:
|
||||
pass # Invalid referral code, just ignore
|
||||
|
||||
# Send activation email
|
||||
current_site = get_current_site(request)
|
||||
mail_subject = 'Activate your Referral Rewards account.'
|
||||
message = render_to_string('core/emails/activation_email.html', {
|
||||
'user': user,
|
||||
'domain': current_site.domain,
|
||||
'protocol': 'https' if request.is_secure() else 'http',
|
||||
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
|
||||
'token': account_activation_token.make_token(user),
|
||||
})
|
||||
to_email = form.cleaned_data.get('email')
|
||||
email = EmailMessage(
|
||||
mail_subject, message, to=[to_email]
|
||||
)
|
||||
try:
|
||||
email.send()
|
||||
send_activation_email(request, user)
|
||||
messages.success(request, 'Please confirm your email address to complete the registration. Check your inbox.')
|
||||
except Exception as e:
|
||||
messages.error(request, f'Error sending email: {str(e)}. Please contact support.')
|
||||
@ -54,6 +79,34 @@ def signup(request):
|
||||
form = SignupForm()
|
||||
return render(request, 'core/signup.html', {'form': form})
|
||||
|
||||
def resend_activation(request):
|
||||
if request.user.is_authenticated:
|
||||
return redirect('dashboard')
|
||||
|
||||
if request.method == 'POST':
|
||||
form = ResendActivationForm(request.POST)
|
||||
if form.is_valid():
|
||||
email_addr = form.cleaned_data.get('email')
|
||||
try:
|
||||
user = User.objects.get(email=email_addr)
|
||||
if not user.is_active:
|
||||
send_activation_email(request, user)
|
||||
messages.success(request, 'A new activation email has been sent. Please check your inbox.')
|
||||
return redirect('login')
|
||||
else:
|
||||
messages.info(request, 'This account is already active. Please log in.')
|
||||
return redirect('login')
|
||||
except User.DoesNotExist:
|
||||
# Security: Don't reveal if email exists, just say it's sent if it's inactive
|
||||
messages.success(request, 'If an inactive account with that email exists, an activation email has been sent.')
|
||||
return redirect('login')
|
||||
except Exception as e:
|
||||
messages.error(request, f'Error sending email: {str(e)}. Please contact support.')
|
||||
else:
|
||||
form = ResendActivationForm()
|
||||
|
||||
return render(request, 'core/resend_activation.html', {'form': form})
|
||||
|
||||
def activate(request, uidb64, token):
|
||||
try:
|
||||
uid = force_str(urlsafe_base64_decode(uidb64))
|
||||
@ -63,6 +116,21 @@ def activate(request, uidb64, token):
|
||||
if user is not None and account_activation_token.check_token(user, token):
|
||||
user.is_active = True
|
||||
user.save()
|
||||
|
||||
# Complete referral if exists
|
||||
referral = Referral.objects.filter(referred_user=user, status='pending').first()
|
||||
if referral:
|
||||
referral.status = 'successful'
|
||||
referral.completed_at = timezone.now()
|
||||
referral.save()
|
||||
|
||||
# Reward referrer (e.g. add 10 points)
|
||||
referrer_profile = referral.referrer.profile
|
||||
referrer_profile.points += 10
|
||||
referrer_profile.save()
|
||||
|
||||
messages.info(request, f'You were successfully referred by {referral.referrer.username}!')
|
||||
|
||||
login(request, user)
|
||||
messages.success(request, 'Thank you for your email confirmation. Now you can enjoy our services.')
|
||||
return redirect('dashboard')
|
||||
@ -72,10 +140,23 @@ def activate(request, uidb64, token):
|
||||
|
||||
@login_required
|
||||
def dashboard(request):
|
||||
# Ensure profile exists (though signal should handle it)
|
||||
profile, created = Profile.objects.get_or_create(user=request.user)
|
||||
return render(request, 'core/dashboard.html', {'profile': profile})
|
||||
|
||||
# Get successful referrals
|
||||
referrals = Referral.objects.filter(referrer=request.user, status__in=['successful', 'rewarded']).order_by('-completed_at')
|
||||
|
||||
current_site = get_current_site(request)
|
||||
domain = current_site.domain
|
||||
protocol = 'https' if request.is_secure() else 'http'
|
||||
referral_link = f"{protocol}://{domain}/?ref={profile.referral_code}"
|
||||
|
||||
context = {
|
||||
'profile': profile,
|
||||
'referrals': referrals,
|
||||
'referral_link': referral_link,
|
||||
}
|
||||
return render(request, 'core/dashboard.html', context)
|
||||
|
||||
def logout_view(request):
|
||||
logout(request)
|
||||
return redirect('home')
|
||||
return redirect('home')
|
||||
Loading…
x
Reference in New Issue
Block a user