Skip to content

Commit

Permalink
Merge pull request #18 from happychuks/main
Browse files Browse the repository at this point in the history
feat: reconfigured the subscribe action
  • Loading branch information
happychuks authored Aug 20, 2024
2 parents 5db604e + bfc6d4e commit e0b3ef6
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 47 deletions.
42 changes: 26 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Before running the application, ensure you have the following:
4. Setup Environment Variables:

Create a .env file in the root directory using the .env.example template and add all required variables:

```env
DJANGO_SETTINGS_MODULE='core.config.local' #for Dev environment
Expand All @@ -65,7 +66,14 @@ Before running the application, ensure you have the following:
DB_USER=<enter username>
DB_PASS=<enter password>
DB_HOST=localhost
DB_PORT=5432
DB_PORT=5432
SITE_URL='http://localhost:8000'
# Django smtp
EMAIL_HOST = 'smtp.gmail.com' # Example using Gmail
EMAIL_HOST_USER = 'enter your email'
EMAIL_HOST_PASSWORD = 'enter password' #for Gmail, generate app password
```

5. Run the application in development mode:
Expand All @@ -76,34 +84,36 @@ Before running the application, ensure you have the following:
python3 manage.py makemigrations # To compile the migrations
python3 manage.py migrate # To migrate the changes in Database
python3 manage.py runserver # To run the API server
redis-server # to start redis-server
celery -A core worker -l info # to run celery
celery -A core beat -l info # to run celery beat
```

- Start Client:
- Start Research Client:

```bash
cd client # enter the client directory
npm install
npm install react-scripts@latest --legacy-peer-deps #to resolve dependency issues
npm run build
npm start # To run the the client server
cd research # enter the research directory
npm install pnpm # do this if you dont have pnpm installed
pnpm install
pnpm start # To run the the research server
```

6. API Testing: `http://127.0.0.1:8000/api/<ROUTE>`

| Method | Route | Description |
| :----: | :---------------: | :-----------------: |
| GET | articles/ | List all articles |
| POST | articles/ | Add an article |
| Method | Route | Description |
| :----: | :----------------: | :-----------------: |
| GET | articles/ | List all articles |
| POST | articles/ | Add an article |
| GET | articles/<uuid:pk> | Retrieve an article |
| PATCH | articles/<uuid:pk> | Update an article |
| DELETE | articles/<uuid:pk> | Delete an article |

7. Client Testing: `http://localhost:3000/<ROUTE>`
7. Client Testing: `http://localhost:4321`

| Method | Route | Description |
| :----: | :---------------: | :-----------------: |
| GET | articles/ | List all articles |
| GET | articles/<uuid:pk> | Retrieve an article |
| Method | Route | Description |
| :----: | :-------: | :-----------------: |
| GET | / | List all articles |
| GET | <uuid:pk> | Retrieve an article |

8. Model Testing: run `python manage.py test`

Expand Down
104 changes: 89 additions & 15 deletions research/src/layouts/Footer.astro
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,97 @@
</div>
</div>

<div class="flex items-center justify-center" id="subscribe">
<div class="flex items-center justify-center text-white" id="subscribe">
<div class="text-center flex flex-col justify-center gap-4 w-max">
<div>
<h3>Your Ethereum Edge</h3><p>
Get first-hand research delivered by our team of experts.
</p>
</div><div class="flex justify-center">
<input
type="email"
class="outline-none rounded-l bg-black border border-white w-max-content p-2 text-sm w-full border-r-none"
value=""
/><button
class="rounded-r bg-[#91b208] px-4 py-2 font-bold min-w-[110px] min-h-[42px]"
>Subscribe</button>
</div><span class="text-sm"></span>
<div>
<h3>Your Ethereum Edge</h3>
<p class="text-white">
Get first-hand research delivered by our team of experts.
</p>
</div>
<form
action="http://127.0.0.1:8000/newsletter/subscribe/"
method="post"
id="subscribe-form"
class="flex justify-center"
>
<!-- CSRF token will be added dynamically -->
<input
type="email"
name="email"
placeholder="Enter your email"
required
class="outline-none rounded-l bg-white border border-black w-max-content p-2 text-sm w-full border-r-none text-black"
/>
<button
type="submit"
class="rounded-r bg-[#91b208] px-4 py-2 font-bold min-w-[110px] min-h-[42px] text-white"
>
Subscribe
</button>
</form>
<span id="response-message" class="text-sm"></span>
</div>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('subscribe-form');

// Fetch CSRF token from Django backend
fetch('http://127.0.0.1:8000/get-csrf-token/')
.then(response => response.json())
.then(data => {
const csrfToken = data.csrfToken;

// Add CSRF token as a hidden input field
if (form) {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'csrfmiddlewaretoken';
input.value = csrfToken;
form.appendChild(input);
}
})
.catch(error => console.error('Error fetching CSRF token:', error));

// Handle form submission
if (form) {
form.addEventListener('submit', function(event) {
event.preventDefault();

const formData = new FormData(form);
const csrfToken = form.querySelector('input[name="csrfmiddlewaretoken"]').value;

fetch(form.action, {
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': csrfToken,
},
})
.then(response => response.json())
.then(data => {
const messageElement = document.getElementById('response-message');
if (data.status === 'error') {
messageElement.textContent = data.message || 'An error occurred. Please try again.';
messageElement.style.color = 'red';
} else {
messageElement.textContent = 'Subscription successful!';
messageElement.style.color = 'green';
}
})
.catch(error => {
console.error('Error during form submission:', error);
const messageElement = document.getElementById('response-message');
messageElement.textContent = 'An error occurred. Please try again.';
messageElement.style.color = 'red';
});
});
}
});
</script>
</div>


<div class="grid mt-16 flex justify-center">
<a href="/" class="logo">
Expand Down
7 changes: 7 additions & 0 deletions server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ DB_USER=<enter username>
DB_PASS=<enter password>
DB_HOST=localhost
DB_PORT=5432

SITE_URL='http://localhost:8000'

# Django smtp
EMAIL_HOST = 'smtp.gmail.com' # Example using Gmail
EMAIL_HOST_USER = 'enter your email'
EMAIL_HOST_PASSWORD = 'enter password' #for Gmail, generate app password
27 changes: 13 additions & 14 deletions server/apps/newsletter/views.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.shortcuts import render
from django.http import JsonResponse
from .models import Subscriber
from .forms import SubscribeForm
from django.views.decorators.csrf import csrf_exempt
from django.db import IntegrityError


@csrf_exempt # Only use this if you can't handle CSRF token in your frontend
@csrf_exempt
def subscribe(request):
if request.method == 'POST':
form = SubscribeForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
Subscriber.objects.create(email=email)
return HttpResponse('You have successfully subscribed.')
else:
form = SubscribeForm()

return render(request, 'newsletter/subscribe.html', {'form': form})

email = request.POST.get('email')
if not email:
return JsonResponse({'message': 'Email is required'}, status=400)

try:
Subscriber.objects.create(email=email, is_active=True)
return JsonResponse({'message': 'Subscription successful'}, status=200)
except IntegrityError:
return JsonResponse({'message': 'Email already subscribed'}, status=400)
def unsubscribe(request, email):
try:
subscriber = Subscriber.objects.get(email=email)
Expand Down
4 changes: 3 additions & 1 deletion server/core/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,11 @@

CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"http://127.0.0.1:8000",
"http://127.0.0.1:8000",
"http://localhost:4321",
]

CORS_ALLOW_CREDENTIALS = True

ROOT_URLCONF = 'core.urls'

Expand Down
9 changes: 8 additions & 1 deletion server/core/config/local.py
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
from .base import *
from .base import *


CSRF_TRUSTED_ORIGINS = [
'http://127.0.0.1:8000',
'http://localhost:8000',
'http://localhost:4321',
]

0 comments on commit e0b3ef6

Please sign in to comment.