Skip to content

Commit

Permalink
fix Invites & Referrals
Browse files Browse the repository at this point in the history
  • Loading branch information
JisanAR03 committed Feb 25, 2024
1 parent 832f96f commit 7cf2557
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 86 deletions.
8 changes: 2 additions & 6 deletions blt/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
DomainDetailView,
StatsDetailView,
InviteCreate,
CreateInviteFriend,
ScoreboardView,
CustomObtainAuthToken,
CreateHunt,
Expand Down Expand Up @@ -117,6 +116,8 @@
handler500 = "website.views.handler500"

urlpatterns = [
path('invite-friend/', website.views.invite_friend, name='invite_friend'),
path('referral/', website.views.referral_signup, name='referral_signup'),
path("captcha/", include("captcha.urls")),
re_path(r"^auth/registration/", include("dj_rest_auth.registration.urls")),
path('rest-auth/password/reset/confirm/<str:uidb64>/<str:token>', PasswordResetConfirmView.as_view(),
Expand Down Expand Up @@ -354,11 +355,6 @@
re_path(r"^hunt/$", login_required(HuntCreate.as_view()), name="hunt"),
re_path(r"^hunts/$", ListHunts.as_view(), name="hunts"),
re_path(r"^invite/$", InviteCreate.as_view(template_name="invite.html")),
re_path(
r"^invite-friend/$",
login_required(CreateInviteFriend.as_view()),
name="invite_friend",
),
re_path(r"^terms/$", TemplateView.as_view(template_name="terms.html"),name="terms"),
re_path(r"^about/$", TemplateView.as_view(template_name="about.html")),
re_path(r"^privacypolicy/$", TemplateView.as_view(template_name="privacy.html")),
Expand Down
8 changes: 1 addition & 7 deletions website/forms.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
from django import forms

from .models import InviteFriend, UserProfile, Hunt
from .models import UserProfile, Hunt
from mdeditor.fields import MDTextFormField
from captcha.fields import CaptchaField

class FormInviteFriend(forms.ModelForm):
class Meta:
model = InviteFriend
fields = ['recipient']
widgets = {'recipient': forms.TextInput(attrs={'class': 'form-control'})}


class UserProfileForm(forms.ModelForm):
class Meta:
Expand Down
55 changes: 55 additions & 0 deletions website/migrations/0083_alter_invitefriend_options_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Generated by Django 5.0.2 on 2024-02-25 05:39

import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("website", "0082_issue_reporter_ip_address"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.AlterModelOptions(
name="invitefriend",
options={},
),
migrations.RemoveField(
model_name="invitefriend",
name="recipient",
),
migrations.RemoveField(
model_name="invitefriend",
name="sent",
),
migrations.AddField(
model_name="invitefriend",
name="point_by_referral",
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name="invitefriend",
name="recipients",
field=models.ManyToManyField(
blank=True, related_name="received_invites", to=settings.AUTH_USER_MODEL
),
),
migrations.AddField(
model_name="invitefriend",
name="referral_code",
field=models.CharField(default=uuid.uuid4, editable=False, max_length=100),
),
migrations.AlterField(
model_name="invitefriend",
name="sender",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="sent_invites",
to=settings.AUTH_USER_MODEL,
),
),
]
13 changes: 6 additions & 7 deletions website/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,14 +378,13 @@ class Points(models.Model):


class InviteFriend(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE)
recipient = models.EmailField()
sent = models.DateTimeField(auto_now_add=True, db_index=True)
sender = models.ForeignKey(User, related_name='sent_invites', on_delete=models.CASCADE)
recipients = models.ManyToManyField(User, related_name='received_invites', blank=True)
referral_code = models.CharField(max_length=100, default=uuid.uuid4, editable=False)
point_by_referral = models.IntegerField(default=0)

class Meta:
ordering = ("-sent",)
verbose_name = "invitation"
verbose_name_plural = "invitations"
def __str__(self):
return f"Invite from {self.sender}"


def user_images_path(instance, filename):
Expand Down
48 changes: 24 additions & 24 deletions website/templates/invite_friend.html
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{% extends "base.html" %}
{% block content %}
<form action="{% url 'invite_friend' %}" method="post" class="form-inline">
{% csrf_token %}
<div class="row">
{% for error in form.non_field_errors %}
<div class="col-lg-6">{{ error }}</div>
{% endfor %}
</div>
<div class="row">
<div class="col-lg-10">
{% if form.recipient.errors %}
<div class="alert alert-danger">{{ form.recipient.errors }}</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-lg-10">
<h3 class="page-header">Invite 2 friends and get 1 point!</h3>
<label>Email:</label>
{{ form.recipient }}
<button type="submit" class="btn btn-danger text-black">Invite</button>
</div>
</div>
</form>
{% endblock %}
<div class="mx-auto max-w-lg mt-5">

<div class="mb-4">
<label for="recipient" class="block text-gray-700 text-2xl font-bold mb-2">Share & Earn</label>
<input class="form-control" type="text" value="{{ referral_link }}" id="referralLink" readonly>
<button onclick="copyReferralLink()" class="mt-2 bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">Copy</button> <span> or </span>
<a href="mailto:?subject=Join Me on BLT to Discover and Report Bugs!&body=Hi there!%0D%0A%0D%0AI've been using BLT, a platform where we can discover and report bugs across various applications and websites. It's been an exciting journey, and I believe you too can contribute significantly and benefit from it.%0D%0A%0D%0ABLT allows us to:%0D%0A- Explore and report bugs.%0D%0A- Earn rewards and recognition for our contributions.%0D%0A- Join a community of like-minded individuals passionate about improving software quality.%0D%0A%0D%0AI thought it would be something you're interested in exploring. You can sign up using the link below and start your journey with BLT today!%0D%0A%0D%0A{{ referral_link|urlencode }}%0D%0A%0D%0ALooking forward to seeing you on BLT and tackling challenges together.%0D%0A%0D%0ABest,%0D%0A{{ user.username|urlencode }}" class="inline-block bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded-lg shadow-lg focus:outline-none focus:shadow-outline transition duration-150 ease-in-out"><i class="fas fa-envelope mr-2"></i>Send Mail</a>
</div>
<div class="flex items-center justify-between">
<p class="inline-block align-baseline font-bold text-base text-red-500 hover:text-red-800">
Invite a friend to join the site and earn 2 points!
</p>
</div>
</div>
<script>
function copyReferralLink() {
var copyText = document.getElementById("referralLink");
copyText.select();
copyText.setSelectionRange(0, 99999);
navigator.clipboard.writeText(copyText.value);
alert("Copied to clipboard: " + copyText.value);
}
</script>
{% endblock %}
86 changes: 44 additions & 42 deletions website/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
Company,
IssueScreenshot
)
from .forms import FormInviteFriend, UserProfileForm, HuntForm, CaptchaForm, QuickIssueForm
from .forms import UserProfileForm, HuntForm, CaptchaForm, QuickIssueForm

from decimal import Decimal
from django.conf import settings
Expand All @@ -90,6 +90,8 @@
from django.core.exceptions import ValidationError
from django.http import HttpRequest
from django.utils.timezone import now
from django.contrib.sites.shortcuts import get_current_site
from allauth.account.signals import user_signed_up

def is_valid_https_url(url):
validate = URLValidator(schemes=['https']) # Only allow HTTPS URLs
Expand Down Expand Up @@ -2058,47 +2060,6 @@ def assign_issue_to_user(request, user, **kwargs):
assigner.request = request
assigner.process_issue(user, issue, created, domain)


class CreateInviteFriend(CreateView):
template_name = "invite_friend.html"
model = InviteFriend
form_class = FormInviteFriend
success_url = reverse_lazy("invite_friend")

def form_valid(self, form):
from django.conf import settings
from django.contrib.sites.shortcuts import get_current_site

instance = form.save(commit=False)
instance.sender = self.request.user
instance.save()

site = get_current_site(self.request)

mail_status = send_mail(
"Inivtation to {site} from {user}".format(
site=site.name, user=self.request.user.username
),
"You have been invited by {user} to join {site} community.".format(
user=self.request.user.username, site=site.name
),
settings.DEFAULT_FROM_EMAIL,
[instance.recipient],
)

if (
mail_status
and InviteFriend.objects.filter(sender=self.request.user).count() == 2
):
Points.objects.create(user=self.request.user, score=1)
InviteFriend.objects.filter(sender=self.request.user).delete()

messages.success(
self.request,
"An email has been sent to your friend. Keep inviting your friends and get points!",
)
return HttpResponseRedirect(self.success_url)

@login_required(login_url="/accounts/login")
def follow_user(request, user):
if request.method == "GET":
Expand Down Expand Up @@ -3735,6 +3696,47 @@ def get_context_data(self, **kwargs):

return context

@receiver(user_signed_up)
def handle_user_signup(request, user, **kwargs):
referral_token = request.session.get('ref')
if referral_token:
try:
invite = InviteFriend.objects.get(referral_code=referral_token)
invite.recipients.add(user)
invite.point_by_referral += 2
invite.save()
reward_sender_with_points(invite.sender)
del request.session['ref']
except InviteFriend.DoesNotExist:
pass

def reward_sender_with_points(sender):
# Create or update points for the sender
points, created = Points.objects.get_or_create(user=sender, defaults={'score': 0})
points.score += 2 # Reward 2 points for each successful referral signup
points.save()

def referral_signup(request):
referral_token = request.GET.get('ref')
# check the referral token is present on invitefriend model or not and if present then set the referral token in the session
if referral_token:
try:
invite = InviteFriend.objects.get(referral_code=referral_token)
request.session['ref'] = referral_token
except InviteFriend.DoesNotExist:
messages.error(request, "Invalid referral token")
return redirect('account_signup')
return redirect('account_signup')


def invite_friend(request):
current_site = get_current_site(request)
referral_code, created = InviteFriend.objects.get_or_create(sender=request.user)
referral_link = f"https://{current_site.domain}/referral/?ref={referral_code.referral_code}"
context = {
'referral_link': referral_link,
}
return render(request, 'invite_friend.html', context)

# class CreateIssue(CronJobBase):
# RUN_EVERY_MINS = 1
Expand Down

0 comments on commit 7cf2557

Please sign in to comment.