mirror of
https://github.com/logos-co/open-law.git
synced 2025-01-10 06:46:04 +00:00
Merge branch 'develop' into kostia/feature/serch_functionality
This commit is contained in:
commit
75c0b6b3a8
@ -8,7 +8,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
|
||||
from app import db
|
||||
from app.models.utils import BaseModel
|
||||
from app.logger import log
|
||||
from app import schema as s
|
||||
from app import schema as s, models as m
|
||||
|
||||
|
||||
def gen_uniq_id() -> str:
|
||||
@ -54,6 +54,17 @@ class User(BaseModel, UserMixin):
|
||||
u = s.User.from_orm(self)
|
||||
return u.json()
|
||||
|
||||
@property
|
||||
def contributions(self):
|
||||
contributions = m.Interpretation.query.filter_by(user_id=self.id).all()
|
||||
comments = m.Comment.query.filter_by(user_id=self.id).all()
|
||||
for comment in comments:
|
||||
if comment.parent:
|
||||
contributions.append(comment.parent.interpretation)
|
||||
else:
|
||||
contributions.append(comment.interpretation)
|
||||
return contributions
|
||||
|
||||
|
||||
class AnonymousUser(AnonymousUserMixin):
|
||||
pass
|
||||
|
@ -303,9 +303,10 @@
|
||||
<p class="text-sm mb-3">{{comment.text}}</p>
|
||||
<div class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
|
||||
<span class="text-sm">Created by <a href="{{url_for('user.profile',user_id=comment.user.id)}}" class=" text-blue-500 {% if comment.user.is_deleted %}line-through{% endif %}">{{comment.user.username}}</a> on {{comment.created_at.strftime('%B %d, %Y')}}</span>
|
||||
<span class="space-x-0.5 flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg>
|
||||
</span>
|
||||
<button data-tooltip-target="tooltip-click" data-tooltip-trigger="click" id="copyLinkButton" type="button" class="hover:text-white focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white" data-link="{{ build_qa_url(section.approved_interpretation) }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg>
|
||||
</button>
|
||||
<div id="tooltip-click" role="tooltip" class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"> Link copied! <div class="tooltip-arrow" data-popper-arrow></div> </div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
@ -354,9 +355,10 @@
|
||||
<p class="text-sm mb-3">{{comment.text}}</p>
|
||||
<div class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
|
||||
<span class="text-sm">Created by <a href="{{url_for('user.profile',user_id=comment.user.id)}}" class=" text-blue-500 {% if comment.user.is_deleted %}line-through{% endif %}">{{comment.user.username}}</a> on {{comment.created_at.strftime('%B %d, %Y')}}</span>
|
||||
<span class="space-x-0.5 flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg>
|
||||
</span>
|
||||
<button data-tooltip-target="tooltip-click" data-tooltip-trigger="click" id="copyLinkButton" type="button" class="hover:text-white focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white" data-link="{{ build_qa_url(section.approved_interpretation) }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg>
|
||||
</button>
|
||||
<div id="tooltip-click" role="tooltip" class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"> Link copied! <div class="tooltip-arrow" data-popper-arrow></div> </div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
109
app/templates/book/favorite_books.html
Normal file
109
app/templates/book/favorite_books.html
Normal file
@ -0,0 +1,109 @@
|
||||
<!-- prettier-ignore -->
|
||||
{% extends 'base.html' %}
|
||||
{% set selected_tab='favorite_books' %}
|
||||
{% block content %}
|
||||
|
||||
<div
|
||||
class="md:mr-64 relative overflow-x-auto shadow-md sm:rounded-lg mt-1 h-box w-box flex">
|
||||
{% if not current_user.is_authenticated %}
|
||||
<!-- prettier-ignore -->
|
||||
<div class="mx-auto my-auto h-full w-full p-2">
|
||||
<button type="button" id="connectWalletBtn" class="w-full h-full text-black dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-100 font-medium rounded-lg text-sm px-4 py-2.5 justify-center text-center inline-flex items-center border border-gray-200 dark:border-gray-700"><div class="my-auto"></div> Connect you wallet to see your favorite books! </div></button></div>
|
||||
<!-- prettier-ignore -->
|
||||
{% endif %}
|
||||
{% if current_user.is_authenticated and not books %}
|
||||
<!-- prettier-ignore -->
|
||||
<div class="mx-auto my-auto h-full w-full p-2">
|
||||
<button type="button" data-modal-target="add-book-modal" data-modal-toggle="add-book-modal" class="w-full h-full text-black dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-100 font-medium rounded-lg text-sm px-4 py-2.5 justify-center text-center inline-flex items-center border border-gray-200 dark:border-gray-700"><div class="my-auto"></div><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" /> </svg> You don't have favorite books start to create your own! </div></button></div>
|
||||
<!-- prettier-ignore -->
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
<div class="flex flex-col w-4/5">
|
||||
<h1 class=" text-lg font-extrabold dark:text-white ml-4">Fav books</h1>
|
||||
{% for book in books %}
|
||||
<!-- prettier-ignore -->
|
||||
<dl class="bg-white dark:bg-gray-900 h-max w-full p-5 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||
<dt class="mb-2"><a class="flex flex-col pb-4" href="{{url_for('book.collection_view',book_id=book.id)}}">{{book.label}}</a></dt>
|
||||
<dd class="flex flex-col md:flex-row text-lg font-semibold text-gray-500 md:text-lg dark:text-gray-400">
|
||||
{% if book.versions %}
|
||||
<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="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>
|
||||
<p>{{ book.approved_interpretations|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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
||||
<p>{{ book.approved_comments|length }}</p>
|
||||
</span>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
{% endfor %}
|
||||
{% if current_user.is_authenticated and page.pages > 1 %}
|
||||
<div class="container content-center mt-3 flex bg-white dark:bg-gray-800">
|
||||
<nav aria-label="Page navigation example" class="mx-auto">
|
||||
<ul class="inline-flex items-center -space-x-px">
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.favorite_books') }}?page=1&q={{page.query}}" class="block px-3 py-2 ml-0 leading-tight text-gray-500 bg-white border border-gray-300 rounded-l-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||
<span class="sr-only">First</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M15.79 14.77a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L11.832 10l3.938 3.71a.75.75 0 01.02 1.06zm-6 0a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L5.832 10l3.938 3.71a.75.75 0 01.02 1.06z" clip-rule="evenodd" /> </svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.favorite_books') }}?page={{page.page-1 if page.page > 1 else 1}}&q={{page.query}}" class="block px-3 py-2 ml-0 leading-tight text-gray-500 bg-white border border-gray-300 rounded-l-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||
<span class="sr-only">Previous</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" /> </svg>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% for p in page.pages_for_links %}
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
{% if p == page.page %}
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.favorite_books') }}?page={{p}}&q={{page.query}}" aria-current="page" class="z-10 px-3 py-2 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white">{{p}}</a>
|
||||
{% else %}
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.favorite_books') }}?page={{p}}&q={{page.query}}" class="px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">{{p}}</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.favorite_books') }}?page={{page.page+1 if page.page < page.pages else page.pages}}&q={{page.query}}" class="block px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 rounded-r-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||
<!-- prettier-ignore -->
|
||||
<span class="sr-only">Next</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> </svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.favorite_books') }}?page={{page.pages}}&q={{page.query}}" class="block px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 rounded-r-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||
<!-- prettier-ignore -->
|
||||
<span class="sr-only">Last</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M10.21 14.77a.75.75 0 01.02-1.06L14.168 10 10.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> <path fill-rule="evenodd" d="M4.21 14.77a.75.75 0 01.02-1.06L8.168 10 4.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> </svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- prettier-ignore -->
|
||||
{% endblock %}
|
||||
<!-- prettier-ignore -->
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
150
app/templates/book/my_contributions.html
Normal file
150
app/templates/book/my_contributions.html
Normal file
@ -0,0 +1,150 @@
|
||||
<!-- prettier-ignore -->
|
||||
{% extends 'base.html' %}
|
||||
{% set selected_tab='my_contributions' %}
|
||||
{% block content %}
|
||||
|
||||
<div
|
||||
class="md:mr-64 relative overflow-x-auto shadow-md sm:rounded-lg mt-1 h-box w-box flex">
|
||||
{% if not current_user.is_authenticated %}
|
||||
<!-- prettier-ignore -->
|
||||
<div class="mx-auto my-auto h-full w-full p-2">
|
||||
<button type="button" id="connectWalletBtn" class="w-full h-full text-black dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-100 font-medium rounded-lg text-sm px-4 py-2.5 justify-center text-center inline-flex items-center border border-gray-200 dark:border-gray-700"><div class="my-auto"></div> Connect you wallet to see your contributions! </div></button></div>
|
||||
<!-- prettier-ignore -->
|
||||
{% endif %}
|
||||
{% if current_user.is_authenticated and current_user.stars|length== 0%}
|
||||
<!-- prettier-ignore -->
|
||||
<div class="mx-auto my-auto h-full w-full p-2">
|
||||
<button type="button" data-modal-target="add-book-modal" data-modal-toggle="add-book-modal" class="w-full h-full text-black dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-100 font-medium rounded-lg text-sm px-4 py-2.5 justify-center text-center inline-flex items-center border border-gray-200 dark:border-gray-700"><div class="my-auto"></div><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" /> </svg> You don't have favorite books start to create your own! </div></button></div>
|
||||
<!-- prettier-ignore -->
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
<div class="flex flex-col w-4/5">
|
||||
<h1 class=" text-lg font-extrabold dark:text-white ml-4">My contributions</h1>
|
||||
{% for interpretation in interpretations %}
|
||||
<!-- prettier-ignore -->
|
||||
<dl class="bg-white dark:bg-gray-900 max-w-full p-3 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||
<div class="flex flex-row pb-3 p-3 w-2/3 md:w-10/12">
|
||||
<div class="vote-block flex flex-col m-5 justify-center items-center">
|
||||
{% if interpretation.user_id != current_user.id %}
|
||||
<div class="vote-button cursor-pointer" data-vote-for="interpretation" data-entity-id="{{ interpretation.id }}" data-positive="true">
|
||||
<svg class="w-6 h-6 select-none
|
||||
{% if interpretation.current_user_vote %}
|
||||
stroke-green-500
|
||||
{% endif %}
|
||||
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18" /> </svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<span
|
||||
class="vote-count text-3xl select-none
|
||||
{% if interpretation.vote_count < 0 %}
|
||||
text-red-500
|
||||
{% elif interpretation.vote_count > 0 %}
|
||||
text-green-500
|
||||
{% endif %}
|
||||
"
|
||||
>
|
||||
{{ interpretation.vote_count }}
|
||||
</span>
|
||||
|
||||
{% if interpretation.user_id != current_user.id %}
|
||||
<div class="vote-button cursor-pointer" data-vote-for="interpretation" data-entity-id="{{ interpretation.id }}" data-positive="false">
|
||||
<svg class="w-6 h-6 select-none
|
||||
{% if interpretation.current_user_vote == False %}
|
||||
stroke-red-500
|
||||
{% endif %}
|
||||
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3" /> </svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- prettier-ignore -->
|
||||
<dt class="flex w-full mb-1 text-gray-500 md:text-lg dark:text-gray-400 flex-col">
|
||||
<div class="ql-snow truncate md:max-w-xl">
|
||||
{% set local_breadcrumbs = interpretation.section.breadcrumbs_path %}
|
||||
{% include 'book/local_breadcrumbs_navigation.html'%}
|
||||
<p>{{ interpretation.section.label }}</p>
|
||||
</a>
|
||||
<div class="dark:text-white h-30 ql-editor-readonly">
|
||||
<p>{{ interpretation.text|safe }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex mt-auto align-center justify-between md:w-full">
|
||||
<div>
|
||||
<span class="hidden md:inline-block">Interpretation by</span>
|
||||
<a href="{{url_for('user.profile',user_id=interpretation.user.id)}}" class=" text-blue-500 {% if interpretation.user.is_deleted %}line-through{% endif %}">{{interpretation.user.username}}</a> on {{interpretation.created_at.strftime('%B %d, %Y')}}
|
||||
</div>
|
||||
<div class="flex ml-auto justify-between w-24">
|
||||
<button data-tooltip-target="tooltip-click" data-tooltip-trigger="click" id="copyLinkButton" type="button" class="hover:text-white focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white" data-link="{{ build_qa_url(interpretation) }}"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg> </button>
|
||||
<div id="tooltip-click" role="tooltip" class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"> Link copied! <div class="tooltip-arrow" data-popper-arrow></div> </div>
|
||||
<div class="space-x-0.5 flex items-center">
|
||||
<a class="!cursor-pointer text-no-underline flex items-center" href="{{ build_qa_url(interpretation) }}" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 01-.825-.242m9.345-8.334a2.126 2.126 0 00-.476-.095 48.64 48.64 0 00-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0011.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155" /> </svg>
|
||||
<p>{{interpretation.active_comments | length}}</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dt>
|
||||
</div>
|
||||
</dl>
|
||||
{% endfor %}
|
||||
{% if current_user.is_authenticated and page.pages > 1 %}
|
||||
<div class="container content-center mt-3 flex bg-white dark:bg-gray-800">
|
||||
<nav aria-label="Page navigation example" class="mx-auto">
|
||||
<ul class="inline-flex items-center -space-x-px">
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.my_contributions') }}?page=1&q={{page.query}}" class="block px-3 py-2 ml-0 leading-tight text-gray-500 bg-white border border-gray-300 rounded-l-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||
<span class="sr-only">First</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M15.79 14.77a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L11.832 10l3.938 3.71a.75.75 0 01.02 1.06zm-6 0a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L5.832 10l3.938 3.71a.75.75 0 01.02 1.06z" clip-rule="evenodd" /> </svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.my_contributions') }}?page={{page.page-1 if page.page > 1 else 1}}&q={{page.query}}" class="block px-3 py-2 ml-0 leading-tight text-gray-500 bg-white border border-gray-300 rounded-l-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||
<span class="sr-only">Previous</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" /> </svg>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% for p in page.pages_for_links %}
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
{% if p == page.page %}
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.my_contributions') }}?page={{p}}&q={{page.query}}" aria-current="page" class="z-10 px-3 py-2 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white">{{p}}</a>
|
||||
{% else %}
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.my_contributions') }}?page={{p}}&q={{page.query}}" class="px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">{{p}}</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.my_contributions') }}?page={{page.page+1 if page.page < page.pages else page.pages}}&q={{page.query}}" class="block px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 rounded-r-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||
<!-- prettier-ignore -->
|
||||
<span class="sr-only">Next</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> </svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<!-- prettier-ignore -->
|
||||
<a href="{{ url_for('book.my_contributions') }}?page={{page.pages}}&q={{page.query}}" class="block px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 rounded-r-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||
<!-- prettier-ignore -->
|
||||
<span class="sr-only">Last</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M10.21 14.77a.75.75 0 01.02-1.06L14.168 10 10.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> <path fill-rule="evenodd" d="M4.21 14.77a.75.75 0 01.02-1.06L8.168 10 4.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> </svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- prettier-ignore -->
|
||||
{% endblock %}
|
||||
<!-- prettier-ignore -->
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
@ -19,10 +19,11 @@
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
<div class="flex flex-col w-4/5">
|
||||
<h1 class=" text-lg font-extrabold dark:text-white ml-4">My library</h1>
|
||||
{% for book in books if not book.is_deleted%}
|
||||
<!-- prettier-ignore -->
|
||||
<dl class="bg-white dark:bg-gray-900 h-max w-full p-5 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||
<dt class="mb-2"><a class="flex flex-col pb-4" href="{{url_for('book.collection_view',book_id=book.id)}}">{{book.owner.username}}/{{book.label}}</a></dt>
|
||||
<dt class="mb-2"><a class="flex flex-col pb-4" href="{{url_for('book.collection_view',book_id=book.id)}}">{{book.label}}</a></dt>
|
||||
<dd class="flex flex-col md:flex-row text-lg font-semibold text-gray-500 md:text-lg dark:text-gray-400">
|
||||
{% if book.versions %}
|
||||
<p>
|
||||
@ -46,7 +47,7 @@
|
||||
</dd>
|
||||
</dl>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% if current_user.is_authenticated and page.pages > 1 %}
|
||||
<div class="container content-center mt-3 flex bg-white dark:bg-gray-800">
|
||||
@ -101,8 +102,8 @@
|
||||
</nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'user/add.html' %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- prettier-ignore -->
|
||||
{% endblock %}
|
||||
<!-- prettier-ignore -->
|
@ -61,7 +61,7 @@
|
||||
<dl class="w-md md:w-full text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700">
|
||||
<!-- prettier-ignore -->
|
||||
<div class="text-sm dark:text-white p-3">Comments:</div>
|
||||
{% for comment in interpretation.comments if not comment.is_deleted %}
|
||||
{% for comment in interpretation.comments if not comment.is_deleted and not comment.parent_id%}
|
||||
<!-- prettier-ignore -->
|
||||
<dl class="bg-white dark:bg-gray-900 max-w-full p-3 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||
<div class="flex flex-row pb-3 p-3 w-2/3 md:w-full">
|
||||
|
@ -130,16 +130,16 @@
|
||||
<span class="text-center md:text-left">My Library</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="my-auto">
|
||||
<li class="mx-2 {% if selected_tab == 'my_contributions' %} bg-slate-300 dark:bg-slate-700 rounded-lg {% endif %}">
|
||||
<a
|
||||
href="#"
|
||||
href="{{url_for('book.my_contributions')}}"
|
||||
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
|
||||
<span class="text-center md:text-left">My Contributions</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li class="mx-2 {% if selected_tab == 'favorite_books' %} bg-slate-300 dark:bg-slate-700 rounded-lg {% endif %}">
|
||||
<a
|
||||
href="#"
|
||||
href="{{ url_for('book.favorite_books')}}"
|
||||
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
|
||||
<span class="text-center md:text-left">Favorite Books</span>
|
||||
</a>
|
||||
|
@ -105,7 +105,7 @@
|
||||
{% for book in books if not book.is_deleted %}
|
||||
<!-- prettier-ignore -->
|
||||
<dl class=" bg-white dark:bg-gray-900 max-w-full p-5 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||
<dt class="mb-2"><a class="flex flex-col pb-4" href="{{url_for('book.collection_view',book_id=book.id)}}">{{book.owner.username}}/{{book.label}}</a></dt>
|
||||
<dt class="mb-2"><a class="flex flex-col pb-4" href="{{url_for('book.collection_view',book_id=book.id)}}">{{book.label}}</a></dt>
|
||||
<dd class="flex flex-col md:flex-row text-lg font-semibold text-gray-500 md:text-lg dark:text-gray-400">
|
||||
{% if book.versions %}
|
||||
<p> Last updated by <a href="{{url_for('user.profile',user_id=book.owner.id)}}" class=" text-blue-500 {% if book.owner.is_deleted %}line-through{% endif %}">{{book.owner.username}}</a> on {{book.versions[-1].updated_at.strftime('%B %d, %Y')}} </p>
|
||||
|
@ -45,7 +45,7 @@
|
||||
{% for book in user.books if not book.is_deleted %}
|
||||
<!-- prettier-ignore -->
|
||||
<dl class="bg-white dark:bg-gray-900 h-max w-full p-5 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||
<dt class="mb-2"><a class="flex flex-col pb-4" href="{{url_for('book.collection_view',book_id=book.id)}}">{{book.owner.username}}/{{book.label}}</a></dt>
|
||||
<dt class="mb-2"><a class="flex flex-col pb-4" href="{{url_for('book.collection_view',book_id=book.id)}}">{{book.label}}</a></dt>
|
||||
<dd class="flex flex-col md:flex-row text-lg font-semibold text-gray-500 md:text-lg dark:text-gray-400">
|
||||
{% if book.versions %}
|
||||
<p>
|
||||
|
@ -6,6 +6,7 @@ from flask import (
|
||||
request,
|
||||
)
|
||||
from flask_login import login_required, current_user
|
||||
from sqlalchemy import and_, or_
|
||||
|
||||
from app.controllers import (
|
||||
create_pagination,
|
||||
@ -37,25 +38,20 @@ def get_all():
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/", methods=["GET"])
|
||||
@bp.route("/my_library", methods=["GET"])
|
||||
def my_library():
|
||||
if current_user.is_authenticated:
|
||||
q = request.args.get("q", type=str, default=None)
|
||||
books: m.Book = m.Book.query.order_by(m.Book.id)
|
||||
books = books.filter_by(user_id=current_user.id, is_deleted=False)
|
||||
if q:
|
||||
books = books.filter(m.Book.label.like(f"{q}"))
|
||||
|
||||
pagination = create_pagination(total=books.count())
|
||||
|
||||
return render_template(
|
||||
"book/index.html",
|
||||
"book/my_library.html",
|
||||
books=books.paginate(page=pagination.page, per_page=pagination.per_page),
|
||||
page=pagination,
|
||||
search_query=q,
|
||||
)
|
||||
return render_template(
|
||||
"book/index.html",
|
||||
"book/my_library.html",
|
||||
books=[],
|
||||
)
|
||||
|
||||
@ -137,3 +133,66 @@ def statistic_view(book_id: int):
|
||||
flash("Book not found", "danger")
|
||||
return redirect(url_for("book.my_library"))
|
||||
return render_template("book/stat.html", book=book)
|
||||
|
||||
|
||||
@bp.route("/favorite_books", methods=["GET"])
|
||||
def favorite_books():
|
||||
if current_user.is_authenticated:
|
||||
books = (
|
||||
db.session.query(
|
||||
m.Book,
|
||||
)
|
||||
.filter(
|
||||
and_(
|
||||
m.Book.id == m.BookStar.book_id,
|
||||
m.BookStar.user_id == current_user.id,
|
||||
m.Book.is_deleted.is_(False),
|
||||
)
|
||||
)
|
||||
.order_by(m.Book.created_at.desc())
|
||||
)
|
||||
|
||||
books = books.filter_by(is_deleted=False)
|
||||
pagination = create_pagination(total=books.count())
|
||||
|
||||
return render_template(
|
||||
"book/favorite_books.html",
|
||||
books=books.paginate(page=pagination.page, per_page=pagination.per_page),
|
||||
page=pagination,
|
||||
)
|
||||
return render_template("book/favorite_books.html", books=[])
|
||||
|
||||
|
||||
@bp.route("/my_contributions", methods=["GET"])
|
||||
def my_contributions():
|
||||
interpretations = (
|
||||
db.session.query(
|
||||
m.Interpretation,
|
||||
)
|
||||
.filter(
|
||||
or_(
|
||||
and_(
|
||||
m.Interpretation.id == m.Comment.interpretation_id,
|
||||
m.Comment.user_id == current_user.id,
|
||||
m.Comment.is_deleted.is_(False),
|
||||
m.Interpretation.is_deleted.is_(False),
|
||||
),
|
||||
and_(
|
||||
m.Interpretation.user_id == current_user.id,
|
||||
m.Interpretation.is_deleted.is_(False),
|
||||
),
|
||||
)
|
||||
)
|
||||
.group_by(m.Interpretation.id)
|
||||
.order_by(m.Interpretation.created_at.desc())
|
||||
)
|
||||
|
||||
pagination = create_pagination(total=interpretations.count())
|
||||
|
||||
return render_template(
|
||||
"book/my_contributions.html",
|
||||
interpretations=interpretations.paginate(
|
||||
page=pagination.page, per_page=pagination.per_page
|
||||
),
|
||||
page=pagination,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user