-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: like button for candidate forms
- Loading branch information
1 parent
8d3f49e
commit 5ce578c
Showing
5 changed files
with
238 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import frappe | ||
|
||
|
||
@frappe.whitelist() | ||
def toggle_like(reference_doctype: str, reference_name: str, comment_email: str) -> None: | ||
""" | ||
Add a 'Like' comment to the specified document. | ||
Args: | ||
reference_doctype (str): The doctype of the document being liked. | ||
reference_name (str): The name of the document being liked. | ||
comment_email (str): The email of the user liking the document. | ||
Returns: | ||
None | ||
Raises: | ||
ValueError: If any of the input parameters are invalid. | ||
frappe.exceptions.ValidationError: If the document cannot be inserted. | ||
""" | ||
if not reference_doctype or not reference_name or not comment_email: | ||
raise ValueError("All parameters must be provided and non-empty.") | ||
|
||
try: | ||
if is_already_liked( | ||
reference_doctype=reference_doctype, | ||
reference_name=reference_name, | ||
comment_email=comment_email, | ||
): | ||
frappe.db.delete( | ||
"Comment", | ||
{ | ||
"reference_doctype": reference_doctype, | ||
"reference_name": reference_name, | ||
"comment_email": comment_email, | ||
"comment_type": "Like", | ||
}, | ||
) | ||
else: | ||
like = frappe.get_doc( | ||
{ | ||
"doctype": "Comment", | ||
"comment_type": "Like", | ||
"reference_doctype": reference_doctype, | ||
"reference_name": reference_name, | ||
"comment_email": comment_email, | ||
"content": "Liked", | ||
} | ||
) | ||
like.insert(ignore_permissions=True) | ||
except Exception as e: | ||
frappe.log_error(message=str(e), title="Like Doc Insertion Failed") | ||
frappe.throw(frappe.ValidationError) | ||
|
||
|
||
@frappe.whitelist(allow_guest=True) | ||
def get_likes_count(reference_doctype: str, reference_name: str) -> int: | ||
""" | ||
Get the count of likes for the specified document. | ||
Args: | ||
reference_doctype (str): The doctype of the document. | ||
reference_name (str): The name of the document. | ||
Returns: | ||
int: The number of likes for the document. | ||
""" | ||
|
||
if not reference_doctype or not reference_name: | ||
raise ValueError( | ||
"Both reference_doctype and reference_name must be provided and non-empty." | ||
) | ||
|
||
return frappe.db.count( | ||
"Comment", | ||
filters={ | ||
"reference_doctype": reference_doctype, | ||
"reference_name": reference_name, | ||
"comment_type": "Like", | ||
}, | ||
) | ||
|
||
|
||
@frappe.whitelist() | ||
def is_already_liked(reference_doctype: str, reference_name: str, comment_email: str) -> bool: | ||
""" | ||
Check if the specified document has already been liked by the given email. | ||
Args: | ||
reference_doctype (str): The doctype of the document. | ||
reference_name (str): The name of the document. | ||
comment_email (str): The email of the user. | ||
Returns: | ||
bool: True if the document is already liked by the given email, False otherwise. | ||
""" | ||
|
||
if not reference_doctype or not reference_name or not comment_email: | ||
raise ValueError("All parameters must be provided and non-empty.") | ||
|
||
return ( | ||
frappe.db.exists( | ||
"Comment", | ||
{ | ||
"reference_doctype": reference_doctype, | ||
"reference_name": reference_name, | ||
"comment_email": comment_email, | ||
"comment_type": "Like", | ||
}, | ||
) | ||
is not None | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<template> | ||
<button | ||
class="flex divide-x-2 border rounded-sm hover:bg-gray-50 text-sm font-medium group transition-all ease-in-out duration-500" | ||
:class=" | ||
alreadyLiked.data | ||
? 'bg-red-600 text-white hover:bg-red-700 border-red-800 divide-red-800' | ||
: '' | ||
" | ||
@click="handleLike()" | ||
> | ||
<div class="flex gap-1 py-2 px-4 items-center"> | ||
<IconHeart | ||
size="1rem" | ||
stroke="2" | ||
class="group-hover:stroke-red-500" | ||
:class="alreadyLiked.data ? 'fill-white group-hover:stroke-white' : ''" | ||
/> | ||
<span v-if="alreadyLiked.data">Liked</span> | ||
<span v-else>Like</span> | ||
</div> | ||
<div class="p-2 min-w-12 gap-1 flex items-center justify-center"> | ||
<span>{{ likeCount.data }}</span> | ||
</div> | ||
</button> | ||
</template> | ||
<script setup> | ||
import { inject } from 'vue' | ||
import { checkAlreadyLiked, getLikeCount, toggleLike } from '@/utils/like' | ||
import { IconHeart } from '@tabler/icons-vue' | ||
const session = inject('$session') | ||
const props = defineProps({ | ||
referenceDoctype: { | ||
type: String, | ||
required: true, | ||
}, | ||
referenceName: { | ||
type: String, | ||
required: true, | ||
}, | ||
}) | ||
const alreadyLiked = checkAlreadyLiked( | ||
props.referenceDoctype, | ||
props.referenceName, | ||
session.user, | ||
) | ||
const likeCount = getLikeCount(props.referenceDoctype, props.referenceName) | ||
const handleLike = () => { | ||
const like = toggleLike( | ||
props.referenceDoctype, | ||
props.referenceName, | ||
session.user, | ||
) | ||
like.fetch().then(() => { | ||
likeCount.fetch() | ||
alreadyLiked.fetch() | ||
}) | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { createResource } from 'frappe-ui' | ||
|
||
export const toggleLike = ( | ||
reference_doctype, | ||
reference_name, | ||
comment_email, | ||
) => { | ||
return createResource({ | ||
url: 'ballot.api.like.toggle_like', | ||
makeParams() { | ||
return { | ||
reference_doctype: reference_doctype, | ||
reference_name: reference_name, | ||
comment_email: comment_email, | ||
} | ||
}, | ||
onSuccess() { | ||
return [1, 'Liked Successfully'] | ||
}, | ||
onError(err) { | ||
return [0, err.messages] | ||
}, | ||
}) | ||
} | ||
|
||
export const checkAlreadyLiked = ( | ||
reference_doctype, | ||
reference_name, | ||
comment_email, | ||
) => { | ||
return createResource({ | ||
url: 'ballot.api.like.is_already_liked', | ||
makeParams() { | ||
return { | ||
comment_email: comment_email, | ||
reference_doctype: reference_doctype, | ||
reference_name: reference_name, | ||
} | ||
}, | ||
auto: true, | ||
}) | ||
} | ||
|
||
export const getLikeCount = (reference_doctype, reference_name) => { | ||
return createResource({ | ||
url: 'ballot.api.like.get_likes_count', | ||
makeParams() { | ||
return { | ||
reference_doctype: reference_doctype, | ||
reference_name: reference_name, | ||
} | ||
}, | ||
auto: true, | ||
}) | ||
} |