Implement bookmarking

This commit is contained in:
Yihao Wang
2025-07-13 23:49:26 +12:00
parent 0e09e9e027
commit 0d3a17a923
2 changed files with 45 additions and 5 deletions

View File

@@ -18,6 +18,11 @@ import { useNavigate } from 'react-router-dom';
import _ from 'lodash'; import _ from 'lodash';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
import { getToolCategoryTitle } from '@utils/string'; import { getToolCategoryTitle } from '@utils/string';
import {
getBookmarkedToolPaths,
isBookmarked,
toggleBookmarked
} from '@utils/bookmark';
const GroupHeader = styled('div')(({ theme }) => ({ const GroupHeader = styled('div')(({ theme }) => ({
position: 'sticky', position: 'sticky',
@@ -33,7 +38,12 @@ const GroupHeader = styled('div')(({ theme }) => ({
const GroupItems = styled('ul')({ const GroupItems = styled('ul')({
padding: 0 padding: 0
}); });
const exampleTools: { label: string; url: string }[] = [
type ToolInfo = {
label: string;
url: string;
};
const exampleTools: ToolInfo[] = [
{ {
label: 'Create a transparent image', label: 'Create a transparent image',
url: '/image-generic/create-transparent' url: '/image-generic/create-transparent'
@@ -51,6 +61,9 @@ export default function Hero() {
const [inputValue, setInputValue] = useState<string>(''); const [inputValue, setInputValue] = useState<string>('');
const theme = useTheme(); const theme = useTheme();
const [filteredTools, setFilteredTools] = useState<DefinedTool[]>(tools); const [filteredTools, setFilteredTools] = useState<DefinedTool[]>(tools);
const [bookmarkedToolPaths, setBookmarkedToolPaths] = useState<string[]>(
getBookmarkedToolPaths()
);
const navigate = useNavigate(); const navigate = useNavigate();
const handleInputChange = ( const handleInputChange = (
event: React.ChangeEvent<{}>, event: React.ChangeEvent<{}>,
@@ -59,6 +72,20 @@ export default function Hero() {
setInputValue(newInputValue); setInputValue(newInputValue);
setFilteredTools(filterTools(tools, newInputValue)); setFilteredTools(filterTools(tools, newInputValue));
}; };
const toolsMap = new Map<string, ToolInfo>();
for (const tool of filteredTools) {
toolsMap.set(tool.path, {
label: tool.name,
url: '/' + tool.path
});
}
const displayedTools =
bookmarkedToolPaths.length > 0
? bookmarkedToolPaths
.map((path) => toolsMap.get(path))
.filter((tools) => tools != undefined)
: exampleTools;
return ( return (
<Box width={{ xs: '90%', md: '80%', lg: '60%' }}> <Box width={{ xs: '90%', md: '80%', lg: '60%' }}>
@@ -127,6 +154,19 @@ export default function Hero() {
<Typography fontWeight={'bold'}>{option.name}</Typography> <Typography fontWeight={'bold'}>{option.name}</Typography>
<Typography fontSize={12}>{option.shortDescription}</Typography> <Typography fontSize={12}>{option.shortDescription}</Typography>
</Box> </Box>
<Icon
fontSize={20}
onClick={(e) => {
e.stopPropagation();
toggleBookmarked(option);
setBookmarkedToolPaths(getBookmarkedToolPaths());
}}
icon={
isBookmarked(option)
? 'mdi:bookmark'
: 'mdi:bookmark-plus-outline'
}
/>
</Stack> </Stack>
</Box> </Box>
)} )}
@@ -137,7 +177,7 @@ export default function Hero() {
}} }}
/> />
<Grid container spacing={2} mt={2}> <Grid container spacing={2} mt={2}>
{exampleTools.map((tool) => ( {displayedTools.map((tool) => (
<Grid <Grid
onClick={() => onClick={() =>
navigate(tool.url.startsWith('/') ? tool.url : `/${tool.url}`) navigate(tool.url.startsWith('/') ? tool.url : `/${tool.url}`)

View File

@@ -2,12 +2,12 @@ import { DefinedTool } from '@tools/defineTool';
const bookmarkedToolsKey = 'bookmarkedTools'; const bookmarkedToolsKey = 'bookmarkedTools';
export function getBookmarkedTools(): string[] { export function getBookmarkedToolPaths(): string[] {
return localStorage.getItem(bookmarkedToolsKey)?.split(',') ?? []; return localStorage.getItem(bookmarkedToolsKey)?.split(',') ?? [];
} }
export function isBookmarked(tool: DefinedTool): boolean { export function isBookmarked(tool: DefinedTool): boolean {
return getBookmarkedTools().some((path) => path === tool.path); return getBookmarkedToolPaths().some((path) => path === tool.path);
} }
export function toggleBookmarked(tool: DefinedTool) { export function toggleBookmarked(tool: DefinedTool) {
@@ -21,7 +21,7 @@ export function toggleBookmarked(tool: DefinedTool) {
function bookmark(tool: DefinedTool) { function bookmark(tool: DefinedTool) {
localStorage.setItem( localStorage.setItem(
bookmarkedToolsKey, bookmarkedToolsKey,
tool.path + localStorage.getItem(bookmarkedToolsKey) tool.path + ',' + (localStorage.getItem(bookmarkedToolsKey) ?? '')
); );
} }