diff --git a/apps/cyberstorm-remix/app/c/community.tsx b/apps/cyberstorm-remix/app/c/community.tsx index f7eecba13..69777f7c5 100644 --- a/apps/cyberstorm-remix/app/c/community.tsx +++ b/apps/cyberstorm-remix/app/c/community.tsx @@ -43,6 +43,10 @@ export async function loader({ request, params }: LoaderFunctionArgs) { const section = searchParams.get("section"); const nsfw = searchParams.get("nsfw"); const deprecated = searchParams.get("deprecated"); + const created_after = searchParams.get("created_after"); + const created_before = searchParams.get("created_before"); + const updated_after = searchParams.get("updated_after"); + const updated_before = searchParams.get("updated_before"); return { community: await dapper.getCommunity(params.communityId), filters: await dapper.getCommunityFilters(params.communityId), @@ -58,7 +62,11 @@ export async function loader({ request, params }: LoaderFunctionArgs) { excludedCategories?.split(",") ?? undefined, section ?? "", nsfw === "true" ? true : false, - deprecated === "true" ? true : false + deprecated === "true" ? true : false, + created_after ?? "", + created_before ?? "", + updated_after ?? "", + updated_before ?? "" ), }; } catch (error) { @@ -86,6 +94,10 @@ export async function clientLoader({ request, params }: LoaderFunctionArgs) { const section = searchParams.get("section"); const nsfw = searchParams.get("nsfw"); const deprecated = searchParams.get("deprecated"); + const created_after = searchParams.get("created_after"); + const created_before = searchParams.get("created_before"); + const updated_after = searchParams.get("updated_after"); + const updated_before = searchParams.get("updated_before"); return { community: await dapper.getCommunity(params.communityId), filters: await dapper.getCommunityFilters(params.communityId), @@ -101,7 +113,11 @@ export async function clientLoader({ request, params }: LoaderFunctionArgs) { excludedCategories?.split(",") ?? undefined, section ?? "", nsfw === "true" ? true : false, - deprecated === "true" ? true : false + deprecated === "true" ? true : false, + created_after ?? "", + created_before ?? "", + updated_after ?? "", + updated_before ?? "" ), }; } catch (error) { diff --git a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/PackageSearch.module.css b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/PackageSearch.module.css index 89d0bef15..fade2cd8e 100644 --- a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/PackageSearch.module.css +++ b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/PackageSearch.module.css @@ -34,3 +34,50 @@ .skeletonContent { height: 38rem; } + +.dateFilterHeader { + padding: var(--space--8) var(--space--12); + font-size: var(--font-size--m); +} + +.dateFilterInputs { + display: flex; + flex-direction: column; + gap: 0.5rem; + max-width: fit-content; +} + +.dateFilterInput { + display: flex; + flex-direction: row; + align-items: center; + padding: var(--space--10) var(--space--14); + border: var(--border-width--2) solid var(--border-color); + + border-radius: var(--border-radius--8); + color: var(--color-text--tertiary); + font-weight: var(--font-weight-medium); + + font-size: var(--font-size--l); + line-height: normal; + background-color: var(--color-surface--4); + outline: none; + transition: ease-out var(--animation-length-l); + + --border-color: transparent; +} + +.dateFilterInput:hover { + --border-color: var(--color-border--highlight); +} + +.dateFilterInput:focus-within { + color: var(--color-text--default); + background-color: var(--color-black); + + --border-color: var(--color-border--highlight); +} + +.dateFilterInput::placeholder { + color: var(--color-text--tertiary); +} diff --git a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/PackageSearch.tsx b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/PackageSearch.tsx index a19d57811..4bf0ba466 100644 --- a/apps/cyberstorm-remix/app/commonComponents/PackageSearch/PackageSearch.tsx +++ b/apps/cyberstorm-remix/app/commonComponents/PackageSearch/PackageSearch.tsx @@ -53,6 +53,10 @@ export function PackageSearch(props: Props) { const [nsfw, setNsfw] = useState(false); const [page, setPage] = useState(1); const [order, setOrder] = useState(PackageOrderOptions.Updated); + const [createdAfter, setCreatedAfter] = useState(""); + const [createdBefore, setCreatedBefore] = useState(""); + const [updatedAfter, setUpdatedAfter] = useState(""); + const [updatedBefore, setUpdatedBefore] = useState(""); const deferredCategories = useDeferredValue(categories); const deferredDeprecated = useDeferredValue(deprecated); @@ -71,6 +75,11 @@ export function PackageSearch(props: Props) { const [debouncedSearchValue] = useDebounce(searchValue, 300); + const deferredCreatedAfter = useDeferredValue(createdAfter); + const deferredCreatedBefore = useDeferredValue(createdBefore); + const deferredUpdatedAfter = useDeferredValue(updatedAfter); + const deferredUpdatedBefore = useDeferredValue(updatedBefore); + useEffect(() => { if (debouncedSearchValue === "") { searchParams.delete("search"); @@ -126,6 +135,30 @@ export function PackageSearch(props: Props) { searchParams.set("order", deferredOrder); } + if (deferredCreatedAfter === "") { + searchParams.delete("created_after"); + } else { + searchParams.set("created_after", deferredCreatedAfter); + } + + if (deferredCreatedBefore === "") { + searchParams.delete("created_before"); + } else { + searchParams.set("created_before", deferredCreatedBefore); + } + + if (deferredUpdatedAfter === "") { + searchParams.delete("updated_after"); + } else { + searchParams.set("updated_after", deferredUpdatedAfter); + } + + if (deferredUpdatedBefore === "") { + searchParams.delete("updated_before"); + } else { + searchParams.set("updated_before", deferredUpdatedBefore); + } + setSearchParams(searchParams); }, [ debouncedSearchValue, @@ -135,6 +168,10 @@ export function PackageSearch(props: Props) { deferredCategories, deferredPage, deferredOrder, + deferredCreatedAfter, + deferredCreatedBefore, + deferredUpdatedAfter, + deferredUpdatedBefore, ]); return ( @@ -148,6 +185,32 @@ export function PackageSearch(props: Props) {