Skip to content

Commit

Permalink
feature/deeplinks
Browse files Browse the repository at this point in the history
* add: deeplinks
* add: enhanced pagination for large datasets
* add more meta tags
* add data to initial state
* remove preview page, instead link directly into the list
  • Loading branch information
hsjobeki committed Jan 24, 2023
1 parent b9a6352 commit 8679af3
Show file tree
Hide file tree
Showing 35 changed files with 504 additions and 624 deletions.
1 change: 1 addition & 0 deletions components/NixFunctions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {NixFunctions as default} from "./nixFunctions";
56 changes: 56 additions & 0 deletions components/NixFunctions/nixFunctions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Box } from "@mui/system";
import { useMemo } from "react";
import { PageState } from "../../models/internals";
import { byQuery, byType, pipe } from "../../queries";
import { DocItem } from "../../models/nix";
import { BasicList, BasicListItem } from "../basicList";
import FunctionItem from "../functionItem/functionItem";
import { SetPageStateVariable } from "../pageContext";

interface FunctionsProps {
pageState: PageState;
setPageStateVariable: SetPageStateVariable;
}

export function NixFunctions(props: FunctionsProps) {
const { pageState, setPageStateVariable } = props;
const { data, selected, term, filter } = pageState;

const setSelected = setPageStateVariable<string | null>("selected");

const filteredData = useMemo(
() => pipe(byType(filter), byQuery(term))(data),
[filter, term, data]
);

const preRenderedItems: BasicListItem[] = filteredData.map(
(docItem: DocItem) => {
const key = docItem.id;
return {
item: (
<Box
sx={{
width: "100%",
height: "100%",
}}
onClick={!(selected === key) ? () => setSelected(key) : undefined}
>
<FunctionItem
name={docItem.name}
docItem={docItem}
selected={selected === key}
handleClose={() => setSelected(null)}
/>
</Box>
),
key,
};
}
);

return (
<Box sx={{ ml: { xs: 0, md: 2 } }}>
<BasicList items={preRenderedItems} />
</Box>
);
}
103 changes: 0 additions & 103 deletions components/basicList/basicList.spec.tsx

This file was deleted.

132 changes: 56 additions & 76 deletions components/basicList/basicList.tsx
Original file line number Diff line number Diff line change
@@ -1,114 +1,90 @@
import React, { useState, useMemo, useEffect } from "react";
import {
Box,
IconButton,
List,
ListItem,
Pagination,
Stack,
Typography,
Grid,
Slide,
Collapse,
Grow,
} from "@mui/material";
import { BasicDataItem, BasicDataViewProps } from "../../types/basicDataView";
import React, { useMemo, useState } from "react";
import { Box, List, ListItem, Stack, TablePagination } from "@mui/material";
import { BasicDataViewProps } from "../../types/basicDataView";
import { SearchInput } from "../searchInput";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import ClearIcon from "@mui/icons-material/Clear";

import { NixType, nixTypes } from "../../types/nix";
import { Filter } from "../searchInput/searchInput";
import { useRouter } from "next/router";
import { FunctionOfTheDay } from "../functionOfTheDay";
import { usePageContext } from "../pageContext";
import { useMobile } from "../layout/layout";
import { EmptyRecordsPlaceholder } from "../emptyRecordsPlaceholder";
import { FunctionOfTheDay } from "../functionOfTheDay";

export type BasicListItem = {
item: React.ReactNode;
key: string;
};
export type BasicListProps = BasicDataViewProps & {
handleFilter: (filter: Filter | ((curr: Filter) => Filter)) => void;
filter: Filter;
term: string;
selected?: string | null;
itemsPerPage: number;
};

type ViewMode = "explore" | "browse";
export function BasicList(props: BasicListProps) {
const {
items,
pageCount = 1,
itemsPerPage,
handleSearch,
handleFilter,
selected = "",
filter,
term,
} = props;

const [page, setPage] = useState<number>(1);
export function BasicList(props: BasicListProps) {
const { items } = props;
const { pageState, setPageStateVariable, resetQueries } = usePageContext();
const isMobile = useMobile();
const { page, itemsPerPage, filter, term, FOTD, data } = pageState;
const [mode, setMode] = useState<ViewMode>("explore");

const router = useRouter();
useEffect(() => {
const { query } = router;
if (query?.page) {
if (typeof query.page === "string") {
const page = Number(query.page);
setPage(page);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router]);
const setPage = setPageStateVariable<number>("page");
const setTerm = setPageStateVariable<string>("term");
const setFilter = setPageStateVariable<Filter>("filter");
const setItemsPerPage = setPageStateVariable<number>("itemsPerPage");

const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setItemsPerPage(parseInt(event.target.value, 10));
setPage(1);
};
const pageItems = useMemo(() => {
const startIdx = (page - 1) * itemsPerPage;
const endIdx = page * itemsPerPage;
return items.slice(startIdx, endIdx);
}, [page, items, itemsPerPage]);

const handlePageChange = (
_event: React.ChangeEvent<unknown>,
event: React.MouseEvent<HTMLButtonElement> | null,
value: number
) => {
setPage(value);
setPage(value + 1);
};
const handleClear = () => {
resetQueries();
};

const _handleFilter = (filter: Filter | ((curr: Filter) => Filter)) => {
setMode("browse");
handleFilter(filter);
const handleFilter = (filter: Filter | ((curr: Filter) => Filter)) => {
setFilter(filter);
setPage(1);
};

const _handleSearch = (term: string) => {
setMode("browse");
handleSearch && handleSearch(term);

const handleSearch = (term: string) => {
setTerm(term);
setPage(1);
};

const showFunctionExplore =
const showFunctionOfTheDay =
mode === "explore" &&
filter.to === "any" &&
filter.from === "any" &&
term === "";
term === "" &&
FOTD === true;
return (
<Stack>
<SearchInput
handleFilter={_handleFilter}
handleFilter={handleFilter}
handleClear={handleClear}
placeholder="search nix functions"
handleSearch={_handleSearch}
page={page}
clearSearch={() => _handleSearch("")}
handleSearch={handleSearch}
/>
{showFunctionExplore ? (
<FunctionOfTheDay handleClose={() => setMode("browse")} />

{showFunctionOfTheDay ? (
<FunctionOfTheDay
data={data}
handleClose={() => {
setMode("browse");
}}
/>
) : (
<List aria-label="basic-list" sx={{ pt: 0 }}>
{items.length ? (
Expand All @@ -134,16 +110,20 @@ export function BasicList(props: BasicListProps) {
)}
</List>
)}

{Math.ceil(items.length / itemsPerPage) > 0 && !showFunctionExplore && (
<Pagination
hideNextButton
hidePrevButton
{!showFunctionOfTheDay && (
<TablePagination
component={"div"}
sx={{ display: "flex", justifyContent: "center", mt: 1, mb: 10 }}
count={Math.ceil(items.length / itemsPerPage) || 1}
count={items.length}
color="primary"
page={page}
onChange={handlePageChange}
page={page - 1}
onPageChange={handlePageChange}
rowsPerPage={itemsPerPage}
labelRowsPerPage={"per Page"}
rowsPerPageOptions={[10, 20, 50, 100]}
onRowsPerPageChange={handleChangeRowsPerPage}
showFirstButton={!isMobile}
showLastButton={!isMobile}
/>
)}
</Stack>
Expand Down
11 changes: 11 additions & 0 deletions components/codeHighlight/codeHighlight.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

.hljs {
padding-left: 0 !important;
padding-top: 0 !important;
}
.hljs .pre {
width: 100%;
}
.hljs .nix {
overflow-x: scroll;
}
Loading

1 comment on commit 8679af3

@vercel
Copy link

@vercel vercel bot commented on 8679af3 Jan 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

noogle – ./

noogle-gold.vercel.app
noogle-git-main-hsjobeki.vercel.app
noogle-hsjobeki.vercel.app

Please sign in to comment.