server continue
This commit is contained in:
@@ -4,68 +4,28 @@ import Card, { Post } from "./Card";
|
||||
export interface PostSortingProps {
|
||||
posts: Post[];
|
||||
privilegeLevel: "anonymous" | "admin" | "user";
|
||||
filters?: string;
|
||||
sort?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* PostSorting Component
|
||||
*
|
||||
* Note: This component has been simplified - filtering and sorting
|
||||
* are now handled server-side via the blog.getPosts tRPC query.
|
||||
*
|
||||
* This component now only renders the posts that have already been
|
||||
* filtered and sorted by the server.
|
||||
*/
|
||||
export default function PostSorting(props: PostSortingProps) {
|
||||
const postsToFilter = () => {
|
||||
const filterSet = new Set<number>();
|
||||
|
||||
if (!props.filters) return filterSet;
|
||||
|
||||
const filterTags = props.filters.split("|");
|
||||
|
||||
props.posts.forEach((post) => {
|
||||
if (post.tags) {
|
||||
const postTags = post.tags.split(",");
|
||||
const hasMatchingTag = postTags.some((tag) =>
|
||||
filterTags.includes(tag.slice(1))
|
||||
);
|
||||
if (hasMatchingTag) {
|
||||
filterSet.add(post.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return filterSet;
|
||||
};
|
||||
|
||||
const filteredPosts = () => {
|
||||
return props.posts.filter((post) => {
|
||||
return !postsToFilter().has(post.id);
|
||||
});
|
||||
};
|
||||
|
||||
const sortedPosts = () => {
|
||||
const posts = filteredPosts();
|
||||
|
||||
switch (props.sort) {
|
||||
case "newest":
|
||||
return [...posts];
|
||||
case "oldest":
|
||||
return [...posts].reverse();
|
||||
case "most liked":
|
||||
return [...posts].sort((a, b) => b.total_likes - a.total_likes);
|
||||
case "most read":
|
||||
return [...posts].sort((a, b) => b.reads - a.reads);
|
||||
case "most comments":
|
||||
return [...posts].sort((a, b) => b.total_comments - a.total_comments);
|
||||
default:
|
||||
return [...posts].reverse();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Show
|
||||
when={!(props.posts.length > 0 && filteredPosts().length === 0)}
|
||||
when={props.posts.length > 0}
|
||||
fallback={
|
||||
<div class="pt-12 text-center text-2xl tracking-wide italic">
|
||||
All posts filtered out!
|
||||
No posts found!
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<For each={sortedPosts()}>
|
||||
<For each={props.posts}>
|
||||
{(post) => (
|
||||
<div class="my-4">
|
||||
<Card post={post} privilegeLevel={props.privilegeLevel} />
|
||||
|
||||
@@ -4,11 +4,11 @@ import Check from "~/components/icons/Check";
|
||||
import UpDownArrows from "~/components/icons/UpDownArrows";
|
||||
|
||||
const sorting = [
|
||||
{ val: "Newest" },
|
||||
{ val: "Oldest" },
|
||||
{ val: "Most Liked" },
|
||||
{ val: "Most Read" },
|
||||
{ val: "Most Comments" }
|
||||
{ val: "newest", label: "Newest" },
|
||||
{ val: "oldest", label: "Oldest" },
|
||||
{ val: "most_liked", label: "Most Liked" },
|
||||
{ val: "most_read", label: "Most Read" },
|
||||
{ val: "most_comments", label: "Most Comments" }
|
||||
];
|
||||
|
||||
export interface PostSortingSelectProps {}
|
||||
@@ -23,14 +23,14 @@ export default function PostSortingSelect(props: PostSortingSelectProps) {
|
||||
const currentFilters = () => searchParams.filter || null;
|
||||
|
||||
createEffect(() => {
|
||||
let newRoute = location.pathname + "?sort=" + selected().val.toLowerCase();
|
||||
let newRoute = location.pathname + "?sort=" + selected().val;
|
||||
if (currentFilters()) {
|
||||
newRoute += "&filter=" + currentFilters();
|
||||
}
|
||||
navigate(newRoute);
|
||||
});
|
||||
|
||||
const handleSelect = (sort: { val: string }) => {
|
||||
const handleSelect = (sort: { val: string; label: string }) => {
|
||||
setSelected(sort);
|
||||
setIsOpen(false);
|
||||
};
|
||||
@@ -42,7 +42,7 @@ export default function PostSortingSelect(props: PostSortingSelectProps) {
|
||||
onClick={() => setIsOpen(!isOpen())}
|
||||
class="focus-visible:border-peach focus-visible:ring-offset-peach bg-surface0 focus-visible:ring-opacity-75 relative w-full cursor-default rounded-lg py-2 pr-10 pl-3 text-left shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 sm:text-sm"
|
||||
>
|
||||
<span class="block truncate">{selected().val}</span>
|
||||
<span class="block truncate">{selected().label}</span>
|
||||
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
||||
<UpDownArrows
|
||||
strokeWidth={1.5}
|
||||
@@ -71,7 +71,7 @@ export default function PostSortingSelect(props: PostSortingSelectProps) {
|
||||
selected().val === sort.val ? "font-medium" : "font-normal"
|
||||
}`}
|
||||
>
|
||||
{sort.val}
|
||||
{sort.label}
|
||||
</span>
|
||||
<Show when={selected().val === sort.val}>
|
||||
<span class="text-peach absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
|
||||
Reference in New Issue
Block a user