mirror of https://github.com/logos-co/open-law.git
book star front end + favorited tab content
This commit is contained in:
parent
ddfcddeecd
commit
ea68e88999
|
@ -1,4 +1,6 @@
|
|||
from app import db
|
||||
from flask_login import current_user
|
||||
|
||||
from app import db, models as m
|
||||
from app.models.utils import BaseModel
|
||||
|
||||
|
||||
|
@ -23,3 +25,12 @@ class Book(BaseModel):
|
|||
@property
|
||||
def last_version(self):
|
||||
return self.versions[-1]
|
||||
|
||||
@property
|
||||
def current_user_has_star(self):
|
||||
if current_user.is_authenticated:
|
||||
book_star: m.BookStar = m.BookStar.query.filter_by(
|
||||
user_id=current_user.id, book_id=self.id
|
||||
).first()
|
||||
if book_star:
|
||||
return True
|
||||
|
|
File diff suppressed because one or more lines are too long
143031
app/static/js/main.js
143031
app/static/js/main.js
File diff suppressed because one or more lines are too long
|
@ -29,9 +29,9 @@
|
|||
</p>
|
||||
{% endif %}
|
||||
<div class="flex ml-auto align-center justify-center space-x-3">
|
||||
<span class="space-x-0.5 flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
|
||||
<p>{{ book.stars|length }}</p>
|
||||
<span class="book-star-block space-x-0.5 flex items-center">
|
||||
<svg class="star-btn cursor-pointer w-4 h-4 inline-flex mr-1 {% if book.current_user_has_star %}fill-yellow-300{% endif %}" data-book-id={{ book.id }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
|
||||
<p class="total-stars">{{ book.stars|length }}</p>
|
||||
</span>
|
||||
<span class="space-x-0.5 flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
||||
|
|
|
@ -38,8 +38,15 @@
|
|||
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"> <tr> <th scope="col" class="px-6 py-3"> Username </th> <th scope="col" class="px-6 py-3"> Address </th> </tr> </thead>
|
||||
<tbody>
|
||||
{% for star in book.stars %}
|
||||
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700"> <th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"> {{star.user.username}} </th> <td class="px-6 py-4"> {{star.user.wallet_id}} </td> </tr>
|
||||
{% for user in book.stars %}
|
||||
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{user.username}}
|
||||
</th>
|
||||
<td class="px-6 py-4">
|
||||
{{user.wallet_id}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -108,9 +108,9 @@
|
|||
<p> Last updated on {{book.versions[-1].updated_at.strftime('%B %d, %Y')}} </p>
|
||||
{% endif %}
|
||||
<div class="flex ml-auto align-center justify-center space-x-3">
|
||||
<span class="space-x-0.5 flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
|
||||
<p>{{ book.stars|length }}</p>
|
||||
<span class="book-star-block space-x-0.5 flex items-center">
|
||||
<svg class="star-btn cursor-pointer w-4 h-4 inline-flex mr-1 {% if book.current_user_has_star %}fill-yellow-300{% endif %}" data-book-id={{ book.id }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
|
||||
<a href={{ url_for('book.statistic_view', book_id=book.id ) }} class="total-stars">{{ book.stars|length }}</a>
|
||||
</span>
|
||||
<span class="space-x-0.5 flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
||||
|
|
|
@ -154,8 +154,7 @@ def statistic_view(book_id: int):
|
|||
log(log.WARNING, "Book with id [%s] not found", book_id)
|
||||
flash("Book not found", "danger")
|
||||
return redirect(url_for("book.my_library"))
|
||||
else:
|
||||
return render_template("book/stat.html", book=book)
|
||||
return render_template("book/stat.html", book=book)
|
||||
|
||||
|
||||
@bp.route("/<int:book_id>/<int:collection_id>/subcollections", methods=["GET"])
|
||||
|
|
|
@ -7,6 +7,7 @@ import {initComments} from './comment';
|
|||
import {initVote} from './vote';
|
||||
import {initTheme} from './theme';
|
||||
import {initApprove} from './approve';
|
||||
import {initStar} from './star';
|
||||
|
||||
initBooks();
|
||||
initContributors();
|
||||
|
@ -17,3 +18,4 @@ initComments();
|
|||
initVote();
|
||||
initTheme();
|
||||
initApprove();
|
||||
initStar();
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
const starClickEventListener = async (btn: Element, totalStars: Element) => {
|
||||
const bookId = btn.getAttribute('data-book-id');
|
||||
|
||||
const requestUrl = '/star/' + bookId;
|
||||
const response = await fetch(requestUrl, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
const json = await response.json();
|
||||
const currentUserStar = json.current_user_star;
|
||||
const starsCount = json.stars_count;
|
||||
|
||||
totalStars.innerHTML = starsCount;
|
||||
|
||||
btn.classList.remove('fill-yellow-300');
|
||||
if (currentUserStar) {
|
||||
btn.classList.add('fill-yellow-300');
|
||||
} else {
|
||||
btn.classList.remove('fill-yellow-300');
|
||||
}
|
||||
};
|
||||
|
||||
export function initStar() {
|
||||
const bookStarsBlocks = document.querySelectorAll('.book-star-block');
|
||||
|
||||
bookStarsBlocks.forEach(bookStarsBlock => {
|
||||
const bookStarBtn = bookStarsBlock.querySelector('.star-btn');
|
||||
const totalStarsDiv = bookStarsBlock.querySelector('.total-stars');
|
||||
|
||||
bookStarBtn.addEventListener('click', () => {
|
||||
starClickEventListener(bookStarBtn, totalStarsDiv);
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue