| 1 | import { type Component, Show } from "solid-js";
|
|---|
| 2 | import { formatDate } from "@/utils";
|
|---|
| 3 | import { useAuth } from "@/context/AuthContext";
|
|---|
| 4 | import type { BlogPost } from "@/api/blog";
|
|---|
| 5 |
|
|---|
| 6 | interface BlogCardProps {
|
|---|
| 7 | blog: BlogPost;
|
|---|
| 8 | openBlog: (blog: BlogPost) => void;
|
|---|
| 9 | onLike: (blogId: number) => void;
|
|---|
| 10 | onEdit: (blog: BlogPost) => void;
|
|---|
| 11 | onDelete: (blogId: number) => void;
|
|---|
| 12 | }
|
|---|
| 13 |
|
|---|
| 14 | const BlogCard: Component<BlogCardProps> = (props) => {
|
|---|
| 15 | const { user } = useAuth();
|
|---|
| 16 | const isOwner = () => user()?.userId === props.blog.patientId;
|
|---|
| 17 |
|
|---|
| 18 | const handleDelete = () => {
|
|---|
| 19 | if (confirm("Are you sure you want to delete this blog post?")) {
|
|---|
| 20 | props.onDelete(props.blog.idBlog);
|
|---|
| 21 | }
|
|---|
| 22 | };
|
|---|
| 23 |
|
|---|
| 24 | return (
|
|---|
| 25 | <div class="bg-white p-6 rounded-lg shadow-md border border-gray-200 hover:shadow-lg transition-shadow">
|
|---|
| 26 | <div class="flex justify-between items-start">
|
|---|
| 27 | <div class="flex-1">
|
|---|
| 28 | <h2
|
|---|
| 29 | onClick={() => props.openBlog(props.blog)}
|
|---|
| 30 | class="text-2xl font-bold text-gray-900 mb-1 cursor-pointer hover:text-blue-600 transition-colors"
|
|---|
| 31 | >
|
|---|
| 32 | {props.blog.title}
|
|---|
| 33 | </h2>
|
|---|
| 34 | <div class="flex items-center gap-2 text-sm text-gray-600">
|
|---|
| 35 | <span class="font-medium">{props.blog.patientName}</span>
|
|---|
| 36 | <span>•</span>
|
|---|
| 37 | <span>{formatDate(props.blog.dateOfPost)}</span>
|
|---|
| 38 | </div>
|
|---|
| 39 | </div>
|
|---|
| 40 | <Show when={isOwner()}>
|
|---|
| 41 | <div class="flex items-center gap-2 ml-4">
|
|---|
| 42 | <button
|
|---|
| 43 | onClick={() => props.onEdit(props.blog)}
|
|---|
| 44 | class="text-gray-400 hover:text-blue-600 transition-colors cursor-pointer"
|
|---|
| 45 | title="Edit blog"
|
|---|
| 46 | >
|
|---|
| 47 | <svg
|
|---|
| 48 | class="w-5 h-5"
|
|---|
| 49 | fill="none"
|
|---|
| 50 | stroke="currentColor"
|
|---|
| 51 | viewBox="0 0 24 24"
|
|---|
| 52 | >
|
|---|
| 53 | <path
|
|---|
| 54 | stroke-linecap="round"
|
|---|
| 55 | stroke-linejoin="round"
|
|---|
| 56 | stroke-width="2"
|
|---|
| 57 | d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
|
|---|
| 58 | />
|
|---|
| 59 | </svg>
|
|---|
| 60 | </button>
|
|---|
| 61 | <button
|
|---|
| 62 | onClick={handleDelete}
|
|---|
| 63 | class="text-gray-400 hover:text-red-600 transition-colors cursor-pointer"
|
|---|
| 64 | title="Delete blog"
|
|---|
| 65 | >
|
|---|
| 66 | <svg
|
|---|
| 67 | class="w-5 h-5"
|
|---|
| 68 | fill="none"
|
|---|
| 69 | stroke="currentColor"
|
|---|
| 70 | viewBox="0 0 24 24"
|
|---|
| 71 | >
|
|---|
| 72 | <path
|
|---|
| 73 | stroke-linecap="round"
|
|---|
| 74 | stroke-linejoin="round"
|
|---|
| 75 | stroke-width="2"
|
|---|
| 76 | d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
|
|---|
| 77 | />
|
|---|
| 78 | </svg>
|
|---|
| 79 | </button>
|
|---|
| 80 | </div>
|
|---|
| 81 | </Show>
|
|---|
| 82 | </div>
|
|---|
| 83 |
|
|---|
| 84 | <div class="flex items-center gap-4 mt-4 pt-4 border-t border-gray-200">
|
|---|
| 85 | <button
|
|---|
| 86 | onClick={() => props.onLike(props.blog.idBlog)}
|
|---|
| 87 | class={`flex items-center gap-2 px-3 py-1 rounded-md transition-colors cursor-pointer ${
|
|---|
| 88 | props.blog.likedByCurrentUser
|
|---|
| 89 | ? "bg-blue-100 text-blue-700"
|
|---|
| 90 | : "bg-gray-100 text-gray-700 hover:bg-gray-200"
|
|---|
| 91 | }`}
|
|---|
| 92 | >
|
|---|
| 93 | <svg
|
|---|
| 94 | class="w-5 h-5"
|
|---|
| 95 | fill={props.blog.likedByCurrentUser ? "currentColor" : "none"}
|
|---|
| 96 | stroke="currentColor"
|
|---|
| 97 | viewBox="0 0 24 24"
|
|---|
| 98 | >
|
|---|
| 99 | <path
|
|---|
| 100 | stroke-linecap="round"
|
|---|
| 101 | stroke-linejoin="round"
|
|---|
| 102 | stroke-width="2"
|
|---|
| 103 | d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
|
|---|
| 104 | />
|
|---|
| 105 | </svg>
|
|---|
| 106 | <span class="font-medium">{props.blog.likesCount}</span>
|
|---|
| 107 | </button>
|
|---|
| 108 |
|
|---|
| 109 | <button
|
|---|
| 110 | onClick={() => props.openBlog(props.blog)}
|
|---|
| 111 | class="flex items-center gap-2 px-3 py-1 rounded-md bg-gray-100 text-gray-700 hover:bg-gray-200 transition-colors cursor-pointer"
|
|---|
| 112 | >
|
|---|
| 113 | <svg
|
|---|
| 114 | class="w-5 h-5"
|
|---|
| 115 | fill="none"
|
|---|
| 116 | stroke="currentColor"
|
|---|
| 117 | viewBox="0 0 24 24"
|
|---|
| 118 | >
|
|---|
| 119 | <path
|
|---|
| 120 | stroke-linecap="round"
|
|---|
| 121 | stroke-linejoin="round"
|
|---|
| 122 | stroke-width="2"
|
|---|
| 123 | d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"
|
|---|
| 124 | />
|
|---|
| 125 | </svg>
|
|---|
| 126 | <span>{props.blog.commentsCount}</span>
|
|---|
| 127 | </button>
|
|---|
| 128 | </div>
|
|---|
| 129 | </div>
|
|---|
| 130 | );
|
|---|
| 131 | };
|
|---|
| 132 |
|
|---|
| 133 | export default BlogCard;
|
|---|