Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filters on stamps based on img type, and sorting by stamp / supply #21

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions fresh.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ import * as $wallet_address_ from "./routes/wallet/[address].tsx";
import * as $BlockSelector from "./islands/BlockSelector.tsx";
import * as $Header from "./islands/Header.tsx";
import * as $MempoolWeather from "./islands/MempoolWeather.tsx";
import * as $Navigator_navigator from "./islands/Navigator/navigator.tsx";
import * as $PageControl from "./islands/PageControl.tsx";
import * as $StampNavigator from "./islands/StampNavigator.tsx";
import * as $StampSearch from "./islands/StampSearch.tsx";
import * as $Toast_ToastComponent from "./islands/Toast/ToastComponent.tsx";
import * as $Toast_toast from "./islands/Toast/toast.tsx";
Expand Down Expand Up @@ -120,6 +123,9 @@ const manifest = {
"./islands/BlockSelector.tsx": $BlockSelector,
"./islands/Header.tsx": $Header,
"./islands/MempoolWeather.tsx": $MempoolWeather,
"./islands/Navigator/navigator.tsx": $Navigator_navigator,
"./islands/PageControl.tsx": $PageControl,
"./islands/StampNavigator.tsx": $StampNavigator,
"./islands/StampSearch.tsx": $StampSearch,
"./islands/Toast/ToastComponent.tsx": $Toast_ToastComponent,
"./islands/Toast/toast.tsx": $Toast_toast,
Expand Down
58 changes: 58 additions & 0 deletions islands/Navigator/navigator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useContext, useState } from "preact/hooks";
import { createContext } from "preact";

const NavigatorContext = createContext(null);

export const useNavigator = () => useContext(NavigatorContext);

export const NavigatorProvider = ({ children }) => {
const [sortOption, setSortOption] = useState("");
const [filterOption, setFilterOption] = useState<string[]>([]);

const setSortOptionData = (value: string) => {
if (window.history) {
window.history.pushState(
{},
"",
`/stamp?sortBy=${value}&filterBy=${filterOption}`,
);
window.location.reload();
}
setSortOption(value);
console.log("Sort option: ", value);
};

const setFilterOptionData = (value: string) => {
let updatedData;
if (filterOption.includes(value)) {
updatedData = [...filterOption.filter((item) => item != value)];
} else {
updatedData = [...filterOption, value];
}
if (window.history) {
window.history.pushState(
{},
"",
`/stamp?sortBy=${sortOption}&filterBy=${updatedData}`,
);
window.location.reload();
}
setFilterOption(updatedData);
console.log(updatedData);
};

const contextValue = {
sortOption,
setSortOption: setSortOptionData,
filterOption,
setFilter: setFilterOption,
setSort: setSortOption,
setFilterOption: setFilterOptionData,
};
return (
<NavigatorContext.Provider value={contextValue}>
{/* <span class="text-white">SortOption: {sortOption}</span> */}
{children}
</NavigatorContext.Provider>
);
};
138 changes: 138 additions & 0 deletions islands/PageControl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { useNavigator } from "$islands/Navigator/navigator.tsx";
import { StampCard } from "$components/StampCard.tsx";
import { StampRow } from "globals";
import { useEffect, useState } from "preact/hooks";
import { StampsClass } from "$lib/database/index.ts";

// const sortData = (stamps: StampRow[], sortBy: string) => {
// const data = [...stamps];
// if (sortBy == "Supply") {
// return [...data.sort((a: StampRow, b: StampRow) => a.supply - b.supply)];
// } else if (sortBy == "Block") {
// return [
// ...data.sort((a: StampRow, b: StampRow) => a.block_index - b.block_index),
// ];
// } else if (sortBy == "Stamp") {
// return [...data.sort((a: StampRow, b: StampRow) => a.stamp - b.stamp)];
// } else return [...data];
// };

// const filterData = (stamps: StampRow[], filterBy: string[]) => {
// if (filterBy.length == 0) {
// return stamps;
// }
// return stamps.filter((stamp) =>
// filterBy.find((option) =>
// stamp.stamp_mimetype.indexOf(option.toLowerCase()) >= 0
// ) != null
// );
// };

export function PageControl(
{ page, pages, page_size, type = "stamp", stamps = [] }: {
page: number;
pages: number;
page_size: number;
type: "cursed" | "stamp";
stamps: [];
},
) {
const maxPagesToShow = 5;
const currentPage = page;
const totalPages = pages;
const startPage = Math.max(1, currentPage - maxPagesToShow);
const endPage = Math.min(totalPages, currentPage + maxPagesToShow);
const pageItems = [];
const { filterOption, sortOption } = useNavigator();

// useEffect(() => {
// if (stamps.length > 0) {
// console.log("updated!!!!", stamps.length, stamps.at(0));

// setContent([...filterData(sortData(stamps, sortOption), filterOption)]);
// }
// }, [sortOption, filterOption]);

for (let p = startPage; p <= endPage; p++) {
pageItems.push(
<li key={p}>
<a
href={`/${type}?page=${p}&limit=${page_size}&sort=${sortOption}&filter=${filterOption}`}
f-partial={`/${type}?page=${p}&limit=${page_size}`}
class={`flex items-center justify-center px-3 h-8 leading-tight font-medium hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-700 dark:hover:text-white
${
currentPage === p
? "bg-white text-gray-800 dark:bg-gray-400 dark:text-black font-semibold"
: "text-gray-500 bg-white dark:text-gray-400 dark:bg-gray-800"
}`}
>
{p}
</a>
</li>,
);
}

return (
<>
{(stamps.length != 0) &&
(
<nav aria-label="Page navigation">
<ul class="inline-flex items-center -space-x-px text-sm">
<li>
<a
href={`/${type}?page=1&limit=${page_size}`}
f-partial={`/${type}?page=1&limit=${page_size}`}
class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-r-0 border-gray-300 rounded-s-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"
>
{"<<"}
</a>
</li>
<li>
<a
href={`/${type}?page=${
Math.max(1, currentPage - 1)
}&limit=${page_size}`}
f-partial={`/${type}?page=${
Math.max(1, currentPage - 1)
}&limit=${page_size}`}
class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-r-0 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"
>
{"<"}
</a>
</li>
{pageItems}
<li>
<a
href={`/${type}?page=${
Math.min(totalPages, currentPage + 1)
}&limit=${page_size}`}
f-partial={`/${type}?page=${
Math.min(totalPages, currentPage + 1)
}&limit=${page_size}`}
class="flex items-center justify-center px-3 h-8 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"
>
{">"}
</a>
</li>
<li>
<a
href={`/${type}?page=${totalPages}&limit=${page_size}`}
f-partial={`/${type}?page=${totalPages}&limit=${page_size}`}
class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-l-0 border-gray-300 rounded-e-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"
>
{">>"}
</a>
</li>
</ul>
</nav>
)}
<div name="stamps">
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4 py-6 transition-opacity duration-700 ease-in-out">
{stamps.map((stamp: StampRow) => (
<StampCard stamp={stamp} kind="stamp" />
))}
</div>
</div>
</>
);
}
103 changes: 103 additions & 0 deletions islands/StampNavigator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { StampRow } from "globals";
import { useContext, useEffect } from "preact/hooks";
import { useNavigator } from "$islands/Navigator/navigator.tsx";
const filters = ["Png", "Gif", "Svg", "Jpg", "Html"];
const sorts = ["Supply", "Stamp"];
const active = " opacity-50";

interface SortItemInterface {
title: string;
onChange: (id: string) => void;
value: string;
}

interface FilterItemInterface {
title: string;
value: string[];
onChange: (id: string) => void;
}

const SortItem = (props: SortItemInterface) => {
const title = props.title;

return (
<div
class={"flex gap-x-2 items-center cursor-pointer hover:opacity-100 " +
(props.value == props.title ? "opacity-100" : "opacity-15")}
onClick={() => {
props.onChange(title);
}}
>
<img class="rounded-full" src={`/img/${title}.png`} width={30} />
<span>{title}</span>
</div>
);
};

const FilterItem = (props: FilterItemInterface) => {
const title = props.title;
return (
<div
class="flex gap-x-1 items-center "
onClick={() => {
props.onChange(title);
}}
>
<input type="checkbox" checked={props.value.includes(title)} />
<span>{title}</span>
</div>
);
};

export function StampNavigator({ initFilter, initSort }) {
const {
setSortOption,
setFilterOption,
sortOption,
filterOption,
setFilter,
setSort,
} = useNavigator();

useEffect(() => {
console.log(initFilter, initSort, "++++");
if (initFilter) {
console.log(initFilter, "---------------");
setFilter(initFilter);
}
if (initSort) {
console.log(initSort, "-----------------");
setSort(initSort);
}
}, []);
return (
<>
<div class="flex flex-row text-white/80 w-full mb-4">
<span class="w-20">Filter by:</span>
<div class="flex flex-1 border border-gray-600 h-16 px-10 py-6 gap-x-5">
{filters.map((item) => {
return (
<FilterItem
title={item}
onChange={setFilterOption}
value={filterOption}
/>
);
})}
</div>
</div>
<div class="flex flex-row text-white/80 w-full mb-10">
<span class="w-20">Sort by:</span>
<div class="flex flex-1 border gap-x-10 border-gray-600 px-10 py-6 items-center">
{sorts.map((item) => (
<SortItem
title={item}
onChange={setSortOption}
value={sortOption}
/>
))}
</div>
</div>
</>
);
}
40 changes: 34 additions & 6 deletions lib/controller/stamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,58 @@ import {
} from "utils/xcp.ts";
import { BIG_LIMIT } from "utils/constants.ts";

const sortData = (stamps, sortBy) => {
if (sortBy == "Supply") {
return [...stamps.sort((a, b) => a.supply - b.supply)];
} else if (sortBy == "Block") {
return [...stamps.sort((a, b) => a.block_index - b.block_index)];
} else if (sortBy == "Stamp") {
return [...stamps.sort((a, b) => a.stamp - b.stamp)];
}
return [...stamps];
};

const filterData = (stamps, filterBy) => {
if (filterBy.length == 0) {
return stamps;
}
return stamps.filter((stamp) =>
filterBy.find((option) =>
stamp.stamp_mimetype.indexOf(option.toLowerCase()) >= 0
) != null
);
};
export async function api_get_stamps(
page = 0,
page = 1,
page_size = BIG_LIMIT,
order: "DESC" | "ASC" = "DESC",
order: "DESC" | "ASC" = "ASC",
sortBy = "none",
filterBy = [],
) {
try {
const client = await getClient();
const stamps = await StampsClass.get_resumed_stamps_by_page_with_client(
const stamps = await StampsClass.get_resumed_stamps(
client,
page_size,
page,
order,
);
if (!stamps) {
closeClient(client);
throw new Error("No stamps found");
}
console.log("backend: ", sortBy, filterBy);
const total = await StampsClass.get_total_stamps_by_ident_with_client(
client,
["STAMP", "SRC-721"],
);

let data = sortData(filterData(stamps.rows, filterBy), sortBy).slice(
page * page_size - page_size,
page * page_size,
);
console.log(data.length);
releaseClient(client);
return {
stamps: stamps.rows,
stamps: data,
total: total.rows[0].total,
pages: Math.ceil(total.rows[0].total / page_size),
page: page,
Expand Down
Loading
Loading