Skip to content

Commit

Permalink
[Fixes🛠️] errors in pagination and ui updates
Browse files Browse the repository at this point in the history
  • Loading branch information
[esekyi] committed Aug 31, 2024
1 parent baed2ba commit 816039d
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 104 deletions.
2 changes: 1 addition & 1 deletion app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ <h1 class="text-3xl font-bold"><a href="{{ url_for('main.index') }}">SpiceShare<

{% block scripts %}
<script src="{{ url_for('static', filename='js/scripts.js') }}"></script>
<script src="{{ url_for('static', filename='js/recipe_form.js') }}"></script>
<!-- <script src="{{ url_for('static', filename='js/recipe_form.js') }}"></script> -->

{% endblock %}
</body>
Expand Down
71 changes: 29 additions & 42 deletions app/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -141,45 +141,40 @@ <h2 class="text-4xl font-bold mb-8">Ready to Join?</h2>
}, 5000); // Display for 3 seconds


let currentPage = 0;
let currentPage = 1; // Start from page 1
let totalPages = 0;
const recipesPerPage = 3;

function fetchRecipes(page)
{
function fetchRecipes(page) {
fetch(`/api/v1/recipes?page=${page}&per_page=${recipesPerPage}`)
.then(response => response.json())
.then(data =>
{
.then(data => {
const recipeGrid = document.getElementById('recipeGrid');
totalPages = Math.ceil(data.recipes.length / recipesPerPage);
totalPages = data.total_pages; // Get total pages from the response

// Enable/Disable buttons based on current page
document.getElementById('prevButton').disabled = currentPage === 0;
document.getElementById('nextButton').disabled = currentPage >= totalPages - 1;
document.getElementById('prevButton').disabled = currentPage === 1; // Disable if on first page
document.getElementById('nextButton').disabled = currentPage >= totalPages; // Disable if on last page

// Add animation to slide content
recipeGrid.style.opacity = 0;
setTimeout(() =>
{
setTimeout(() => {
recipeGrid.innerHTML = ''; // Clear existing recipes
const start = page * recipesPerPage;
const end = page + recipesPerPage
const visibleRecipes = data.recipes.slice(start, end);

visibleRecipes.forEach(recipes =>
{
// Use the recipes directly from the response
data.recipes.forEach(recipe => {
const recipeCard = `
<div class="bg-white shadow-lg rounded-lg overflow-hidden transform transition-transform duration-500 hover:scale-105">
<div class="h-40 bg-gray-200 flex items-center justify-center">
${recipes.image_url && recipes.image_url.trim() !== '' ? `
<img src="https://recipe-files.s3.eu-north-1.amazonaws.com/recipes/${recipes.image_url}" alt="${recipes.title}" class="w-full h-full object-cover">
${recipe.image_url && recipe.image_url.trim() !== '' ? `
<img src="https://recipe-files.s3.eu-north-1.amazonaws.com/recipes/${recipe.image_url}" alt="${recipe.title}" class="w-full h-full object-cover">
` : `
<span class="text-gray-500">No Image Available</span>
`}
</div>
<div class="p-4">
<h3 class="text-lg font-bold text-gray-800 mb-2">${recipes.title}</h3>
<p class="text-gray-500 text-sm">${new Date(recipes.created_at).toLocaleDateString()} at ${new Date(recipes.created_at).toLocaleTimeString()}</p>
<h3 class="text-lg font-bold text-gray-800 mb-2">${recipe.title}</h3>
<p class="text-gray-500 text-sm">${new Date(recipe.created_at).toLocaleDateString()} at ${new Date(recipe.created_at).toLocaleTimeString()}</p>
<a href="#" class="text-blue-600 mt-2 inline-block">Read More</a>
</div>
</div>
Expand All @@ -191,55 +186,47 @@ <h3 class="text-lg font-bold text-gray-800 mb-2">${recipes.title}</h3>
const images = document.querySelectorAll('img');
let loadedImages = 0;

if (images.length === 0)
{
if (images.length === 0) {
document.getElementById('loader').style.display = 'none'; // No images to load
}

images.forEach((img) =>
{
img.onload = img.onerror = () =>
{ // Consider both load and error events
images.forEach((img) => {
img.onload = img.onerror = () => { // Consider both load and error events
loadedImages++;
if (loadedImages === images.length)
{
if (loadedImages === images.length) {
document.getElementById('loader').style.display = 'none'; // All images have been loaded or errored out
}
};
// If the image is already loaded (from cache), trigger the load event manually
if (img.complete)
{
if (img.complete) {
img.onload();
}
});
}, 500);

})
.catch(error => {
console.error('Error fetching recipes:', error);
});

}

document.getElementById('prevButton').addEventListener('click', () =>
{
if (currentPage > 0)
{
document.getElementById('prevButton').addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
fetchRecipes(currentPage);
}
});

document.getElementById('nextButton').addEventListener('click', () =>
{
if (currentPage < totalPages - 1){
document.getElementById('nextButton').addEventListener('click', () => {
if (currentPage < totalPages) {
currentPage++;
fetchRecipes(currentPage);
}
});

// Initial fetch
window.addEventListener('load', () =>
{
fetchRecipes(currentPage);
});
window.addEventListener('load', () => {
fetchRecipes(currentPage);
});

</script>

Expand Down
4 changes: 2 additions & 2 deletions app/templates/recipes/createPages/create_layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@

<a href="{{ url_for('auth.logout')}}" class="text-blue-800">Logout</a>
{% else %}
<a href="{{ url_for('auth.login')}}" class="text-blue-800 mx-4">Login</a>
<a href="{{ url_for('user_routes.register')}}" class="text-blue-800">Join</a>
<a href="{{ url_for('auth.login')}}" class="text-blue-800 mx-4">Sign In</a>
<a href="{{ url_for('user_routes.register')}}" class="text-blue-800">Sign Up</a>
{% endif %}
</nav>
</div>
Expand Down
4 changes: 2 additions & 2 deletions app/templates/recipes/readPages/read_layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
<a href="{{ url_for('user_routes.user_profile', user_id=current_user.id)}}" class="text-blue-800 mx-4">My Profile</a>
<a href="{{ url_for('auth.logout')}}" class="text-blue-800">Logout</a>
{% else %}
<a href="{{ url_for('auth.login')}}" class="text-blue-800 mx-4">Login</a>
<a href="{{ url_for('user_routes.register')}}" class="text-blue-800">Join</a>
<a href="{{ url_for('auth.login')}}" class="text-blue-800 mx-4">Sign In</a>
<a href="{{ url_for('user_routes.register')}}" class="text-blue-800">Sign Up</a>
{% endif %}
</nav>
</div>
Expand Down
89 changes: 68 additions & 21 deletions app/templates/user_auth/login.html
Original file line number Diff line number Diff line change
@@ -1,24 +1,71 @@
{% extends "base.html" %}
<!DOCTYPE html>
<html lang="en">

{% block title %}
Login - SpiceShare
{% endblock %}
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign In - SpiceShare</title>
<link rel="stylesheet" href="{{url_for('static', filename='css/output.css')}}">
<style>
.toggle-password {
cursor: pointer;
}
</style>
</head>

{% block content %}
<div class="max-w-md mx-auto bg-white p-8 rounded shadow-md">
<h2 class="text-2xl font-semibold text-text mb-6">Login</h2>
<form action="{{ url_for('auth.login') }}" method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="mb-4">
<label for="email" class="block text-sm font-medium text-text">Email:</label>
<input type="email" id="email" name="email" class="mt-1 p-2 w-full border rounded" required>
</div>
<div class="mb-4">
<label for="password" class="block text-sm font-medium text-text">Password:</label>
<input type="password" id="password" name="password" class="mt-1 p-2 w-full border rounded" required>
</div>
<button type="submit" class="bg-primary text-white py-2 px-4 rounded hover:bg-primary-dark">Login</button>
</form>
</div>
<body class="bg-gray-100 font-poppins flex items-center justify-center min-h-screen">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div id="flashMessageBox"
class="fixed top-4 left-1/2 transform -translate-x-1/2 p-4 w-96 bg-{{ category }} text-white text-center rounded-lg shadow-lg flash-message">
<p>{{ message }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}

{% endblock %}
<!-- Login Form -->
<div class="w-full max-w-md bg-white p-8 rounded-lg shadow-lg">
<h2 class="text-2xl font-bold text-gray-800 mb-6 text-center">Sign In</h2>

<form action="{{ url_for('auth.login')}}" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="mb-4">
<label for="email" class="block text-sm font-medium text-gray-700">Email <span class="text-red-500">*</span></label>
<input type="email" id="email" name="email" required placeholder="[email protected]" autocomplete="on"
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500">
</div>

<div class="mb-6 relative">
<label for="password" class="block text-sm font-medium text-gray-700">Password <span class="text-red-500">*</span></label>
<div class="relative">
<input type="password" name="password" id="password" placeholder="Password" autocomplete="on"
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500">
<button type="button" class="absolute right-3 top-3 text-gray-600"
onclick="togglePasswordVisibility('password', event)">
👁️
</button>
</div>
</div>
<div class="flex items-center mb-6">
<label class="inline-flex items-center text-gray-700">
<input id="remember_me" name="remember_me" type="checkbox" class="form-checkbox text-blue-600">
<span class="ml-2 block text-sm text-gray-900">Remember me</span>
</label>
</div>

<button type="submit"
class="w-full bg-blue-600 hover:bg-blue-700 text-white py-3 rounded-lg font-semibold transition duration-300">Login</button>
</form>
<p class="mt-4 text-center text-sm text-gray-600">
Don't have an account?
<a href="{{ url_for('user_routes.register') }}" class="text-blue-600 hover:underline">Sign Up</a>
</p>
</div>

<script src="{{ url_for('static', filename='js/auth_script.js') }}"></script>

</body>

</html>
Loading

0 comments on commit 816039d

Please sign in to comment.